绑定到数组元素

问题描述 投票:0回答:4

我正在尝试将 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
4个回答
28
投票

无需转换器。您可以像这样直接绑定到

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}"/>

7
投票

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


0
投票

在我的例子中你可以使用这种方式,我想绑定布尔数组的可见性: 背后代码:

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

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


0
投票

作为 Avalonia 初学者,使用 ReactiveObject 投入我的钱。

我发现如果重新创建数组,它将呈现与数组的绑定。

在 C# 中:

// has to recreate the array so Avalonia will render
LoadBarsLevel = Enumerable.Repeat(false, NumberOfBars).ToArray(); 
var level = (int)(args.BrandedLoadingPercentage / (100.0 / NumberOfBars));
Enumerable.Repeat(true, Math.Min(level, 
NumberOfBars)).ToArray().CopyTo(LoadBarsLevel, 0);

在 XAML 中:

  <Panel Canvas.Left="23" Canvas.Top="455" Width="50" Height="50">
      <Image Source="/Assets/LevelGrey.png" />
  </Panel>
  <Panel Canvas.Left="23" Canvas.Top="455" Width="50" Height="50" IsVisible="{Binding LoadBarsLevel[1]}">
      <Image Source="/Assets/LevelGreen.png" />
  </Panel>
© www.soinside.com 2019 - 2024. All rights reserved.