【问题标题】:DataGrid does not updating with ObservableCollectionDataGrid 不使用 ObservableCollection 更新
【发布时间】:2014-06-01 08:59:13
【问题描述】:

我正在尝试学习 MVVM(使用 MVVMLight 工具包)。但我被困住了。

在 ViewModel 中有一个 ObservableCollection

private ObservableCollection<Phone> _phoneNumbers;

public ObservableCollection<Phone> PhoneNumbers
{
    get { return _phoneNumbers; }
    private set
    {
        _phoneNumbers = value;
    }
}

在 ViewModel 构造函数中这样填写 PhoneNumbers = new ObservableCollection&lt;Phone&gt;(Guest.Person.Phones);

考虑有

<DataGrid x:Name="PhoneNumbersDataGrid" HorizontalAlignment="Left" Grid.Column="3" Grid.Row="11" VerticalAlignment="Top" Height="86" Width="auto" ItemsSource="{Binding PhoneNumbers, Mode=OneWay}" AutoGenerateColumns="False" IsReadOnly="True">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding PhoneNumber}" Header="Phone Number" IsReadOnly="True"/>
        <DataGridTemplateColumn Header="Delete">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Button Command="{Binding Guest.DeletePhoneCommand, Mode=OneWay, Source={StaticResource Locator}}">Delete</Button>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

在 DeletePhoneCommand 中,我正在尝试更改 PhoneNumbers,例如

PhoneNumbers = new ObservableCollection<Phone>();
RaisePropertyChanged("PhoneNumbers");

集合变为空,但数据网格显示填充集合,没有任何更改。只有在加载视图时才会触发 Collection 的“get”。即使我 RaisePropertyChanged("PhoneNumbers") 它也不会触发。

我做错了什么?

【问题讨论】:

    标签: c# wpf mvvm datagrid observablecollection


    【解决方案1】:

    如果您想通知收藏的更改,您应该使用Mode = TwoWay

    两种方式都可以使对象的任何变化都反映到 UI 中,并且 UI 中的任何变化都反映在对象中。

    <DataGrid x:Name="PhoneNumbersDataGrid" HorizontalAlignment="Left" Grid.Column="3" Grid.Row="11" VerticalAlignment="Top" Height="86" Width="auto" ItemsSource="{Binding PhoneNumbers, Mode=TwoWay}" AutoGenerateColumns="False" IsReadOnly="True">
                <DataGrid.Columns>
                    <DataGridTextColumn Binding="{Binding PhoneNumber,Mode=TwoWay}" Header="Phone Number" IsReadOnly="True"/>
                    <DataGridTemplateColumn Header="Delete">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Button Command="{Binding Guest.DeletePhoneCommand, Mode=OneWay, Source={StaticResource Locator}}">Delete</Button>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
            </DataGrid>
    

    【讨论】:

    • 默认绑定模式是双向
    • @Tomtom 他明确表示为 OneWay
    • 您可能还想实现 INotifyPropertyChanged 例如... xaml - ItemsSource="{Binding PhoneNumbers, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" c# - set { _phoneNumbers = value; OnPropertyChanged("PhoneNumbers"); }
    【解决方案2】:

    如果我没记错的话,当你重新初始化集合时绑定会被破坏。要解决此问题,您必须处理已初始化的集合。例如:

    使用清除列表

    PhoneNumbers.Clear()

    添加到列表中,使用

    PhoneNumbers.Add(item)

    当您使用 ObservableCollection 时,您无需引发属性更改事件来更新 UI 中的列表。如果您更改列表中项目的属性,您将需要它。

    【讨论】:

      【解决方案3】:

      首先用

      清除列表
      Clear()
      

      然后添加项目

      PhoneNumbers.Add(item)
      

      【讨论】:

      猜你喜欢
      • 2017-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-26
      • 2017-11-21
      相关资源
      最近更新 更多