【问题标题】:Binding to an array element绑定到数组元素
【发布时间】:2011-07-21 21:54:44
【问题描述】:

我正在尝试将 TextBlock 绑定到 ObservableCollection 中的特定元素。 这就是我现在所做的:

private ObservableCollection<double> arr = new ObservableCollection<double>();
public ObservableCollection<double> Arr { get { return arr; } set { arr = value; }  }

testBox.DataContext = this;

private void Button_Click(object sender, RoutedEventArgs e)
{
   Arr[0] += 1.0;
}

    [ValueConversion(typeof(ObservableCollection<double>), typeof(String))]
    public class myObsCollConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            ObservableCollection<double> l = value as ObservableCollection<double>;
            if( l == null )
                return DependencyProperty.UnsetValue;
            int i = int.Parse(parameter.ToString());

            return l[i].ToString();
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return DependencyProperty.UnsetValue;
        }
    }


    <Window.Resources>
        <local:myObsCollConverter x:Key="myConverter"/>
    </Window.Resources>

        <TextBlock Name="testBox" Text="{Binding Path=Arr,Converter={StaticResource myConverter}, ConverterParameter=0}" />

我看到的是 testBox 在创建时显示了 Arr 的第一个值。 但这并不反映此元素的任何更改。 为了在我的文本框中看到对 Arr[0] 的更改,我需要做什么?

【问题讨论】:

    标签: .net wpf xaml data-binding


    【解决方案1】:

    在我想绑定布尔数组的可见性的情况下,您可以使用这种方式: 后面的代码:

    using System.Windows;
    public static readonly DependencyProperty ButtonVisibleProperty =
            DependencyProperty.Register("ButtonVisible", typeof(BindingList<Boolean>), typeof(BaseWindow), new PropertyMetadata(new BindingList<Boolean>()));
     public BindingList<Boolean> ButtonVisible 
        { 
            get { return (BindingList<Boolean>)GetValue(BaseWindow.ButtonVisibleProperty); }
            set 
            {
                SetValue(BaseWindow.ButtonVisibleProperty, value);
                OnPropertyChanged("ButtonVisible");  
            } 
        }
    

    在 Xaml 中:

    Visibility=""{Binding Path=ButtonVisible[0], RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
    

    小心!在我的例子中,祖先类型取决于你的祖先是一个窗口

    【讨论】:

      【解决方案2】:

      不需要转换器。你可以像这样直接绑定到Arr[0]

       <TextBlock Name="testBox" Text="{Binding Path=Arr[0]}"/>
      

      Arr 中的元素需要实现 INotifyPropertyChanged 才能动态更新。

      更新:详细说明:

      public class MyDouble : INotifyPropertyChanged
      {
          public event PropertyChangedEventHandler PropertyChanged;
      
          private double _Value;
          public double Value 
          { 
              get { return _Value; } 
              set { _Value = value; OnPropertyChanged("Value"); }
          }
      
          void OnPropertyChanged(string propertyName)
          {
             var handler = PropertyChanged;
             if (handler != null)
             {
                handler(this, new PropertyChangedEventArgs(propertyName));
             }
          }
      }
      

      然后

       ObservableCollection<MyDouble> Arr { get; set; }
      

      并绑定到

       <TextBlock Name="testBox" Text="{Binding Path=Arr[0].Value}"/>
      

      【讨论】:

      • 难道它不应该工作吗?当值被替换时,ObservableCollection 将引发一个 CollectionChanged 事件......我很惊讶绑定没有注意到这一点。
      • 好吧,你绑定到元素而不是集合,所以我猜 UI 只会监听 PropertyChanged 事件
      • 如果我不想将元素索引 (0) 绑定到另一个控件怎么办?例如我有一个 ComboBox 来选择元素的索引,我的 testBox 应该显示它。
      • 基于该解决方案(即使用 Observable 集合并直接绑定到 Arr[0]”我必须在 Arr.CollectionChanged 上定义一个事件回调,在其中我调用 OnPropertyChanged("Arr")。那元素更改时绑定的工作方式。
      【解决方案3】:

      ObservableCollections 不会将更改传播到存储在属于该集合的对象中的值。它仅在集合本身的内容发生更改(即添加、删除、重新排序的项目)时触发通知。如果您想让您的 UI 在集合中的值发生更改时更新,那么您必须自己单独连接。

      【讨论】:

      • 这是替换项目,而不是修改对象中的内部数据。我刚刚检查过,在这种情况下它触发 CollectionChanged 事件(使用替换操作)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-20
      相关资源
      最近更新 更多