什么时候默认转换器启动?

stu*_*ree 5 wpf converters

使用以下代码,虽然Text属性绑定到DateTime源属性,但我注意到WPF似乎自动将文本转换为DateTime,而不需要编写ValueConverter.有人可以说明这是如何完成的

<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>
Run Code Online (Sandbox Code Playgroud)
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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

Den*_*nis 5

它使用的DateTimeTypeConverter是基类库(编辑:嗯,它本来可以使用TypeConverter,但是从@ DeviantSeev的回答看来它们没有).

您正在谈论的'默认'转换器实际上是TypeConverters(MSDN),它们自从v2.0开始就是.NET Framework的一部分,它们在整个基类库中使用.在WPF类型转换器的另一个例子是ThicknessTypeConverter用于 Padding,MarginBorderThickness特性.它将逗号分隔的字符串转换为Thickness对象.

很多文章可以,如果你想进一步了解他们.

有两个部分使用TypeConverter- 类的实现,然后使用标记属性/类型TypeConverterAttribute.

例如,我最近有一个自定义控件需要char[]我想要设置,Xaml如下所示:

<AutoCompleteTextBox MultiInputDelimiters=",;. " />
Run Code Online (Sandbox Code Playgroud)

用法

[TypeConverter(typeof(CharArrayTypeConverter))]
public char[] MultiInputDelimiters
{
      get { return (char[])GetValue(MultiInputDelimitersProperty); }
      set { SetValue(MultiInputDelimitersProperty, value); }
}
Run Code Online (Sandbox Code Playgroud)

履行

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;
    }

}
Run Code Online (Sandbox Code Playgroud)

什么时候用TypeConverter

您只能TypeDescriptors在编写自定义控件时使用,因为您需要能够使用标记来标记属性TypeDescriptorAttribute.此外,我只会使用TypeConverter如果转换是直接的 - 如上面的例子中我有一个字符串并想要char[]- 或者如果有多种可能的格式我想转换.

IValueConverter当您想要通过数据驱动或传递参数来转换值时,您可以更灵活地编写.例如,WPF中一个非常常见的操作是将a转换boolVisibility; 有从这样的转换三种可能的输出(Visible,Hidden,Collapsed),并用仅两个输入(true,false)难以在决定此TypeConverter.

在我的应用程序中,要实现这两个输入到三个输出问题,我已经编写了一个BoolToVisibilityConverter带有TrueValueFalseValue属性的单个,然后我在我的全局中实例三次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"/>
Run Code Online (Sandbox Code Playgroud)