【问题标题】:Binding to Array Element Doesn't Update绑定到数组元素不更新
【发布时间】:2011-03-25 09:34:47
【问题描述】:

这不是一件容易的事。

我有一个列表框 (elementSelection) 和一个文本块 (elementViewer)。 elementViewer 显示数组的一个元素,该元素由 elementSelection 框选择。所有这些都有效,即使我以编程方式修改数组中的一个元素,更改也会反映在 elementViewer 中。 代码如下:

public class ArrElem : INotifyPropertyChanged
{
    public ArrElem(double d)
    {
        wert = d;
    }

    private double intwert;
    public double wert
    {
        get { return intwert; }
        set
        {
            intwert = value;
            NotifyPropertyChanged("wert");
        }
    }
    // Declare the PropertyChanged event
    public event PropertyChangedEventHandler PropertyChanged;

    // NotifyPropertyChanged will raise the PropertyChanged event passing the
    // source property that is being updated.
    public void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

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

private ObservableCollection<int> indexArrField = new ObservableCollection<int>();
public ObservableCollection<int> indexArr { get { return indexArrField; } set { indexArrField = value; } }


    public MainWindow()
    {
        Arr.Add(new ArrElem(1.1));
        Arr.Add(new ArrElem(2.2));
        for (int i = 0; i < Arr.Count; i++)
        {
            indexArr.Add(i);
        }

        InitializeComponent();
        DataContext = this;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        // this one doesn't show on elementViewer
        //double d = Arr[0].wert + 0.1;
        //Arr.RemoveAt(0);
        //Arr.Insert(0, new ArrElem(d));

        // this one shows on elementViewer
        Arr[0].wert += 0.1;
    }

public class MySpecialMultiConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        int i = int.Parse(values[0].ToString());
        ObservableCollection<ArrElem> arr = values[1] as ObservableCollection<ArrElem>;

        if (arr == null || i >= arr.Count || i < 0)
            return DependencyProperty.UnsetValue;

        return arr[i];
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        object[] ooo = new object[1];
        ooo[0] = DependencyProperty.UnsetValue;
        return ooo;
    }
}



    <local:MySpecialMultiConverter x:Key="multiConverter" />

    <ListBox Name="elementSelection" ItemsSource="{Binding indexArr}"></ListBox>

    <TextBlock Name="elementViewer" Text="{Binding Path=wert}" >
        <TextBlock.DataContext>
            <MultiBinding Converter="{StaticResource multiConverter}">
                <Binding ElementName="elementSelection" Path="SelectedIndex" />
                <Binding Path="Arr" />
            </MultiBinding>
        </TextBlock.DataContext>
    </TextBlock>

现在我的问题: 正如您在 Button_Click 的代码中看到的那样,对单个 ArrElem 的更改显示在 elementViewer 中,但如果我替换 ArrElem elementViewer 不会更新。

在这两种情况下,我必须进行哪些更改才能获得 elementViewer 的更新?

【问题讨论】:

    标签: c# .net wpf xaml data-binding


    【解决方案1】:

    我猜在您从绑定集合中删除列表框后,该列表框不再具有选定项。 (SelectedIndex == -1)。更改后尝试设置:

    var selectedIndex = elementSelection.SelectedIndex;
    double d = Arr[0].wert + 0.1;
    Arr.RemoveAt(0);
    Arr.Insert(0, new ArrElem(d));
    elementSelection.SelectedIndex = selectedIndex;
    

    顺便说一句:您可以将TextBlock 直接绑定到ListBoxSelectedItem 属性。无需编写转换器。

    【讨论】:

    • 不,SelectedIndex 不会改变,重新设置也无济于事。不,我不能在没有转换器的情况下直接绑定到 SelectedItem,因为那时我将无法访问数组元素(或者至少我不知道如何)。
    • SelectedItem 是数组元素。
    • 对不起,我没有看到这个。但这无济于事,SelectedItem 是 indexArr 的元素,而不是 Arr 的元素。我需要这个 indexArray,因为在我的应用程序中应该可以选择目前不存在的数组元素。
    • 啊,我没有看到列表框没有绑定到您传递给转换器的同一数组。问题是,SelectedIndexArr 都没有引发 PropertyChanged 事件,这就是为什么不对 TextBox 上的绑定进行重新评估的原因。尝试使用elementViewer.GetBindingExpression(TextBox.TextProperty).UpdateTarget();
    • GetBindingExpression 返回 null
    猜你喜欢
    • 2011-11-03
    • 2011-12-25
    • 2014-12-27
    • 2011-07-21
    • 2014-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多