问题描述
使用以下代码,尽管Text属性绑定到DateTime源属性,但我注意到WPF似乎自动将文本转换为DateTime,而无需编写ValueConverter。有人可以说明一下如何完成
With the following code, although Text property is bound to a DateTime source property, I noticed WPF seems to automatically convert the text to a DateTime, without me needing to write a ValueConverter. Can someone please shed some light on how this is done
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:WpfApplication1="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525"
>
<StackPanel>
<DatePicker Height="25" Name="datePicker1" Width="213" Text="{Binding Path=DueDate,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</Window>
public class P
{
private DateTime? dueDate = DateTime.Now;
public DateTime? DueDate
{
get { return dueDate; }
set
{
dueDate = value;
}
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
P p = new P();
this.DataContext = p;
}
}
推荐答案
它正在使用基类库中的 DateTimeTypeConverter
(编辑:嗯,它本来可以使用TypeConverter,但是从他们没有这样做)。
It is using the DateTimeTypeConverter
from the Base Class Library ( Well, it could have used a TypeConverter however it appears that from @DeviantSeev's answer that they did not).
您是默认转换器谈论的实际上是 TypeConverters
(),并且自v2.0起它们就成为.NET Framework的一部分,并且在整个基类库中都使用了它们。 WPF中TypeConverters的另一个示例是 ThicknessTypeConverter
,用于 Padding
, Margin
和 BorderThickness
属性。它将逗号分隔的字符串转换为 Thickness
对象。
There 'default' converters you are talking about are actually TypeConverters
(MSDN) and they have been a part of the .NET Framework since v2.0 and they are used through-out the Base Class Libraries. Another example of TypeConverters in WPF is the ThicknessTypeConverter
for Padding
, Margin
, and BorderThickness
properties. It converts a comma-delimited string to a Thickness
object.
有(如果您想) a href = http://www.csharphelp.com/2007/07/c-type-converters-your-friendly-helpers/ rel = nofollow noreferrer>进一步了解它们。
There are plenty of articles available if you want to understand them further.
使用 TypeConverter
有两部分-实现类,然后使用标记您的属性/类型 TypeConverterAttribute
。
There are two parts to using a TypeConverter
- implementation of the class and then marking up your properties/types with TypeConverterAttribute
.
例如,我最近有一个自定义控件,需要一个 char []
,我想从 Xaml
像这样:
For example, I recently had a custom control that required a char[]
that I wanted to set from Xaml
like so:
<AutoCompleteTextBox MultiInputDelimiters=",;. " />
用法
[TypeConverter(typeof(CharArrayTypeConverter))]
public char[] MultiInputDelimiters
{
get { return (char[])GetValue(MultiInputDelimitersProperty); }
set { SetValue(MultiInputDelimitersProperty, value); }
}
实施
public class CharArrayTypeConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return (Type.GetTypeCode(sourceType) == TypeCode.String);
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is string)
return ((string)value).ToCharArray();
return value;
}
}
何时使用 TypeConverter
?
When to use a TypeConverter
?
您只能使用 TypeDescriptors
如果您要编写自定义控件,则需要使用 TypeDescriptorAttribute
标记该属性。如果转换相当简单,我也只会使用 TypeConverter
-如上面的示例中我有一个字符串并想要一个 char [ ]
-或是否有多种可能的格式要转换。
You can only use TypeDescriptors
if you are writing a custom control as you need to be able to mark-up the property with the TypeDescriptorAttribute
. Also I would only use TypeConverter
if the conversion is rather a straight-forward - as in the example above where I have a string and want a char[]
- or if there are multiple possible formats that I want to convert from.
当您想要更大的灵活性来通过数据驱动或传递来转换值时,编写 IValueConverter
参数。例如,在WPF中非常常见的操作是将 bool
转换为 Visibility
;这样的转换有三种可能的输出(可见
,隐藏
,崩溃
),并且只有两个输入( true
, false
),很难在 TypeConverter
。
You write IValueConverter
when you want more flexibility on how the value to converted by driving it by data or a passing a parameter. For example, a very common action in WPF is converting a bool
to Visibility
; there are three possible outputs from such a conversion (Visible
, Hidden
, Collapsed
) and with only two inputs (true
, false
) it difficult to decide this in a TypeConverter
.
在我的应用程序中,为了实现这两个输入到三个输出的问题,我编写了一个 BoolToVisibilityConverter
,其中 TrueValue
和 FalseValue
属性,然后在我的全局 ResourceDictionary $ c中实例化三遍$ c>。 。
In my applications, to achieve this two inputs to three output problem I have written a single BoolToVisibilityConverter
with a TrueValue
and FalseValue
properties and then I instance it three times in my global ResourceDictionary
. .
[ValueConversion(typeof(bool), typeof(Visibility))]
public class BooleanToVisibilityConverter : IValueConverter
{
public Visibility FalseCondition { get; set; }
public Visibility TrueCondition { get; set; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((bool)value) ? TrueCondition : FalseCondition;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if ((bool)value)
return TrueCondition;
return FalseCondition;
}
}
<converters:BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter" FalseCondition="Collapsed" TrueCondition="Visible"/>
<converters:BooleanToVisibilityConverter x:Key="BoolToVisibilityCollapsedConverter" FalseCondition="Visible" TrueCondition="Collapsed"/>
<converters:BooleanToVisibilityConverter x:Key="BoolToVisibilityHiddenConverter" FalseCondition="Visible" TrueCondition="Hidden"/>
<converters:BooleanToVisibilityConverter x:Key="BoolToVisibilityHiddenWhenFalseConverter" FalseCondition="Hidden" TrueCondition="Visible"/>
这篇关于默认转换器何时启动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!