2009-10-21 2 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; 
     } 
    } 
} 

При нажатии на кнопку он изменяет значения первого ряда, но это изменение не отражается в пользовательском интерфейсе. Если я изменю свойство Title, заголовок будет обновляться правильно.

Любые идеи, как я могу назвать INotifyPropertyChanged, чтобы он понял, что элемент массива обновлен?

+0

Это близко .. http://stackoverflow.com/questions/90971/how-do-i-use-inotifypropertychanged-to-update-an-array-binding – Kelly

ответ

7

Причина, по которой ваш существующий код не работает, заключается в том, что вы изменяете значение внутри массива, а не переназначаете весь массив в свойстве. Поэтому вы не будете запускать событие изменения свойств.

Я бы не использовал массив вообще, вместо этого использует ObservableCollection, который реализует INotifyCollectionChanged, с которым привязана инфраструктура привязки WPF, чтобы лучше понимать изменения внутри самой коллекции.

+0

Ищет лучший способ справиться с этим без ObservableCollection, но, похоже, это маршрут, который мне нужно. – Kelly

+0

Можете ли вы добавить пример кода? – Butzke

2

Вместо массива вы можете использовать ObservableCollection<int?>, чтобы сделать всю сантехнику для вас.

Другой вариант может заключаться в том, чтобы сделать контейнер int?, заполнить массив этими и пожар PropertyChanged на этом сетевом устройстве int?.

Смежные вопросы