DataGrid使用INotifyPropertyChanged绑定ObservableCollection而不重新刷新

时间:2014-01-13 21:26:43

标签: c# wpf binding datagrid inotifypropertychanged

我正在将List<Product>绑定到DataGrid并将其属性绑定到DataGridTextColumns,并为我的ListProduct实施INotifyPropertyChanged

当我更改Product的任何属性时,它将在我的DataGrid中更新,但是当添加或删除任何Product时,它将不会在DataGrid中更新

我的DataGrid

    <DataGrid x:Name="ProductList" AutoGenerateColumns="False" IsReadOnly="True">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Id" Binding="{Binding Id}"/>
            <DataGridTextColumn Header="Code" Binding="{Binding Code}"/>
            <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
            <DataGridTextColumn Header="Value" Binding="{Binding Value, StringFormat=R\{0:C\}}"/>
        </DataGrid.Columns>
    </DataGrid>

我的代码背后

public partial class PageProduct : Page, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private ObservableCollection<Pastel> _ListProduct;
    public ObservableCollection<Pastel> ListProduct
    {
        get { return _ListProduct; }
        set
        {
            _ListProduct = value;
            this.OnPropertyChanged("ListProduct");
        }
    }

    public PagePastel()
    {

        InitializeComponent();

        UpdateList();
        ProductList.ItemsSource = ListProduct;   // ProductList is my DataGrid
    }

    private void OnPropertyChanged(string p)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(p));
        }
    }

    private void UpdateList()
    {
        // db is my EntityContext
        ListProduct = new ObservableCollection<Product>(db.Products.ToList());
    }

    private void btDeletar_Click(object sender, RoutedEventArgs e)
    {
        if (ProductList.SelectedItem != null)
        {
            Product product = ProductList.SelectedItem as Product;

            db.Product.Remove(product);
            db.SaveChanges();
            if (SystemMessage.ConfirmDeleteProduct() == MessageBoxResult.No)
                return;

            SystemMessage.ProductDeleteSuccess();
            UpdateList();
        }
        else
            SystemMessage.NoProductSelected();
    }

哪里有问题?添加或删除任何寄存器时,我可以为DataGrid更新列表做什么?


解决方案:https://stackoverflow.com/a/8470177/2209497

1 个答案:

答案 0 :(得分:1)

问题是你要覆盖ListProduct字段引用的ObservableCollection而不是更改ProductList.ItemsSource。这导致ListProduct属性将指向新列表,而ProductList.ItemsSource仍将指向原始列表。

只是在ListProduct上引发PropertyChanged事件将不起作用,因为你没有使用ItemsSource属性的Binding。你有几个选择。

1)将UpdateList更改为:

private void UpdateList()
{
    // db is my EntityContext
    ListProduct = new ObservableCollection<Product>(db.Products.ToList());
    ProductList.ItemsSource = ListProduct;
}

public PagePastel()
{

    InitializeComponent();

    UpdateList();
}

或者什么可能会更好,更改btDeletar_Click只是从ProductList中删除所选项目,如下所示:

private void btDeletar_Click(object sender, RoutedEventArgs e)
{
    if (ProductList.SelectedItem != null)
    {
        Product product = ProductList.SelectedItem as Product;

        db.Product.Remove(product);
        db.SaveChanges();

        // *** Side note, should db.SaveChanges be after this if statement?? ***
        if (SystemMessage.ConfirmDeleteProduct() == MessageBoxResult.No)
            return;

        SystemMessage.ProductDeleteSuccess();
        // Don't call UpdateList just remove the item from the list. 
        // This will raise the CollectionChanged event and the grid will respond accordingly.
        ProductList.Remove(product);
    }
    else
        SystemMessage.NoProductSelected();
}