2009-10-21 49 views
2

我创建了一个小例子来演示我遇到的问题。WPF INotifyPropertyChanged不更新数组属性?

一是我的课:


public class DisplayRow : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    private int?[] values; 
    private string title; 

    public string Title 
    { 
     get { return title; } 
     set 
     { 
      title = value; 
      if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Title")); 
     } 
    } 

    public int?[] Values 
    { 
     get { return values; } 
     set 
     { 
      values = value; 
      if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Values[]")); 
     } 
    } 

    public DisplayRow() 
    { 
     Values = new int?[6]; 
    } 
} 

的问题是价值观的性质,因为它是一个数组。我不确定如何在数组中的元素更新时正确调用INotifyPropertyChanged。

这是我的XAML:

<Window x:Class="WpfApplication5.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300"> 
    <Grid> 
     <ListBox x:Name="MyListBox" Margin="0,0,0,65"> 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <WrapPanel> 
         <TextBlock Text="{Binding Path=Title}" /> 
         <TextBlock Text="{Binding Path=Values[0]}" Margin="5,0,0,0" /> 
         <TextBlock Text="{Binding Path=Values[1]}" Margin="5,0,0,0" /> 
         <TextBlock Text="{Binding Path=Values[2]}" Margin="5,0,0,0" /> 
         <TextBlock Text="{Binding Path=Values[3]}" Margin="5,0,0,0" /> 
         <TextBlock Text="{Binding Path=Values[4]}" Margin="5,0,0,0" /> 
         <TextBlock Text="{Binding Path=Values[5]}" Margin="5,0,0,0" />       
        </WrapPanel> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 
     </ListBox> 
     <Button Height="23" Margin="27,0,0,23" Name="button1" VerticalAlignment="Bottom" HorizontalAlignment="Left" Width="74" Click="button1_Click">Button</Button> 
    </Grid> 
</Window> 

而后面的代码:

public partial class Window1 : Window 
{ 
    private readonly ObservableCollection<DisplayRow> displayRows = new ObservableCollection<DisplayRow>(); 

    public Window1() 
    { 
     InitializeComponent(); 

     displayRows.Add(new DisplayRow {Title = "Item 1", Values = new int?[] {1, 2, 3, 4, 5, 6}}); 
     displayRows.Add(new DisplayRow {Title = "Item 2", Values = new int?[] {7, 8, 9, 10, 11, 12}}); 
     displayRows.Add(new DisplayRow {Title = "Item 3", Values = new int?[] {13, 14, 15, 16, 17, 18}}); 

     MyListBox.ItemsSource = displayRows; 
    } 

    private void button1_Click(object sender, RoutedEventArgs e) 
    { 
     foreach (DisplayRow row in displayRows) 
     { 
      row.Values[0] = 99; 
     } 
    } 
} 

当我点击该按钮,它改变了第一行的值,但这种变化不会反映在UI上。如果我更改Title属性,则标题会正确更新。

任何想法如何我可以调用INotifyPropertyChanged,以便它了解数组元素已更新?

+0

This one is close .. http://stackoverflow.com/questions/90971/how-do-i-use-inotifypropertychanged-to-update-an-array-binding – Kelly 2009-10-21 16:49:18

回答

7

您现有的代码不起作用的原因是因为您要修改数组中的值,而不是将整个数组本身重新分配给属性。因此你不会发射财产变更事件。

我根本不会使用数组,而是使用ObservableCollection代替它,它实现了WPF绑定基础结构挂接的INotifyCollectionChanged,以更好地理解集合本身内的更改。

+0

正在寻找更好的方法来处理这个问题没有ObservableCollection,但看起来这是我需要去的路线。 – Kelly 2009-10-21 19:56:23

+0

你可以添加一个示例代码吗? – Butzke 2014-03-07 11:09:34

2

您可以使用ObservableCollection<int?>而不是阵列来为您完成所有管道工作。

另一种选择可能是制作一个int?容器,用这些容器填充阵列,并在int?的制定者上点火PropertyChanged事件。

相关问题