绑定到数组支持的属性

Hou*_*ell 3 c# wpf xaml

我正在尝试为Windows Phone 7平台构建自定义控件.到目前为止,我已经定义了属性,如果它是一个简单类型(如字符串),它可以正常工作,但这最终需要是一个数组.所以我这样定义我的属性:

    #region Keywords

    public string[] Keywords
    {
        get { return (string[])GetValue(KeywordsProperty); }
        set { SetValue(KeywordsProperty, value); }
    }

    public static readonly DependencyProperty KeywordsProperty =
        DependencyProperty.Register(
            "Keywords",
            typeof(string[]),
            typeof(MyType),
            new PropertyMetadata(null));

    #endregion Keywords
Run Code Online (Sandbox Code Playgroud)

现在我想要顶级支持绑定和XAML,但我无法弄清楚如何通过XAML设置属性.有一个更好的方法吗?

Ray*_*rns 5

在XAML中使用字符串[]

您可以在XAML中实例化您的关键字属性,如下所示:

<MyControl ...>
  <MyControl.Keywords>
    <sys:String>Happy</sys:String>
    <sys:String>Sad</sys:String>
    <sys:String>Angry</sys:String>
  </MyControl.Keywords>
</MyControl>
Run Code Online (Sandbox Code Playgroud)

注意:这假定名称空间声明

xmlns:sys="clr-namespace:System;assembly=mscorlib"
Run Code Online (Sandbox Code Playgroud)

您可以将ItemsControl绑定到关键字,如下所示:

<ListBox ItemsSource="{Binding Keywords}" ...>
Run Code Online (Sandbox Code Playgroud)

在此示例中,每个关键字将显示为单独的ListBox项.

在WPF中为此目的使用字符串[]是完全犹太的,只要保证数组成员永远不会更改(您可以用新的替换数组,但不更改其元素).这是因为数组没有更改通知机制.

如果您的元素可能会改变

如果关键字数组的元素可能会更改,则应使用ObservableCollection而不是数组.使其成为只读CLR属性(不是依赖属性)并在构造函数中初始化它.然后,您可以完全按照上面所示在XAML中填充它,但对集合的任何更改都将立即反映在您的UI中.

我实际上使用自己的集合类,它具有比ObservableCollection更多的功能.只要它实现了INotifyCollectionChanged,使用哪个集合类并不重要.

使用纯XAML使列表可更新

您无法使用绑定更新关键字数组.如果您需要更新关键字并希望完全使用XAML和绑定来完成,则需要创建一个包含字符串的关键字对象类,然后将它们放在ObservableCollection或类似文件中.

的IValueConverter

另一种方法是使用IValueConverter将逗号分隔的字符串列表转换为字符串[],如下所示:

<TextBox Text="{Binding Keywords,
                        Converter={x:Static my:CommaSeparatedConverter.Instance}}" />
Run Code Online (Sandbox Code Playgroud)

转换器将在哪里:

public class CommaSeparatedConverter : IValueConverter
{
  public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  {
    return string.Join(",", (string[])value);
  }
  public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  {
    return ((string)value).Split(',');
  }
}
Run Code Online (Sandbox Code Playgroud)