简体   繁体   English

DataGrid不会刷新

[英]DataGrid won't refresh

I have a DataGrid which is using an ObservableCollection as the ItemsSource. 我有一个使用ObservableCollection作为ItemsSource的DataGrid。

The items in the collection are items of a custom class. 集合中的项目是自定义类的项目。

When I edit one of those items, I can't get the view to update no matter what I do. 当我编辑其中一项时,无论执行什么操作都无法更新视图。 I have tried removing and re-adding all of the items to the collection, and I have tried re-assigning the collection to the grid. 我尝试删除所有项目并将其重新添加到集合中,并且尝试将集合重新分配给网格。

I know the edits are being saved correctly because I can see the changed values in the debugger. 我知道编辑已正确保存,因为我可以在调试器中看到更改的值。

What could possibly be causing this to happen? 有什么可能导致这种情况发生?

Is there some other way I could force the grid to refresh? 还有其他方法可以强制网格刷新吗?

As noted in the ObservableCollection documentation, only insertions and deletions are notified in the collection, which is exposed by the CollectionChanged event. ObservableCollection文档中所述,在集合中仅通知插入​​和删除操作,而CollectionChanged事件公开了该插入和删除操作。 In order to make the items in the ObservableCollection notify a change has been made, the underlying model must implement INotifyPropertyChanged : 为了使ObservableCollection的项目通知已进行更改,基础模型必须实现INotifyPropertyChanged

Account: 帐户:

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace TestUWP
{
    public class Account : INotifyPropertyChanged
    {
        private string _accountName;
        private decimal _amount;

        public string AccountName
        {
            get => _accountName;
            set
            {
                _accountName = value;
                OnPropertyChanged();
            }
        }

        public decimal Amount
        {
            get => _amount;
            set
            {
                _amount = value;
                OnPropertyChanged();
            }
        }


        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

ViewModel + RelayCommand: ViewModel + RelayCommand:

using System;
using System.Collections.ObjectModel;
using System.Windows.Input;

namespace TestUWP
{
    public class AccountViewModel
    {
        public AccountViewModel()
        {
            Accounts = new ObservableCollection<Account>
            {
                new Account {AccountName = "Account 1", Amount = 1000M},
                new Account {AccountName = "Account 2", Amount = 2000M},
                new Account {AccountName = "Account 3", Amount = 3000M},
            };

            AddAccountCommand = new RelayCommand(AddAccount);
            EditAccountCommand = new RelayCommand(EditAccount);
        }

        public ICommand AddAccountCommand { get; }
        public ICommand EditAccountCommand { get; }

        public ObservableCollection<Account> Accounts { get; }

        private void AddAccount()
        {
            Accounts.Add(new Account{AccountName = $"Account {Accounts.Count+1}", Amount = 1000M * (Accounts.Count+1)});
        }

        private void EditAccount()
        {
            Accounts[Accounts.Count - 1].Amount += 200M;
        }
    }

    public class RelayCommand : ICommand
    {
        private readonly Action _execute;
        private readonly Func<bool> _canExecute;
        public event EventHandler CanExecuteChanged;

        public RelayCommand(Action execute, Func<bool> canExecute = null)
        {
            _execute = execute ?? throw new ArgumentNullException(nameof(execute));
            _canExecute = canExecute;
        }

        public bool CanExecute(object parameter) => _canExecute?.Invoke() ?? true;

        public void Execute(object parameter) => _execute();

        public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
    }
}

MainPage: 主页:

<Page
    x:Class="TestUWP.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:TestUWP"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Page.DataContext>
        <local:AccountViewModel />
    </Page.DataContext>

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="0.5*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <ListView Grid.Column="0" Grid.RowSpan="2" ItemsSource="{Binding Accounts}">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="x:String">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>
                        <TextBlock Text="{Binding AccountName}" Grid.Column="0" FontSize="30"/>
                        <TextBlock Text="{Binding Amount}" Grid.Column="1" Margin="30,0,0,0" FontSize="30"/>
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <Button Grid.Column="1" Grid.Row="0" Content="Add" FontSize="50" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Command="{Binding AddAccountCommand}"/>
        <Button Grid.Column="1" Grid.Row="1" Content="Edit" FontSize="50" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Command="{Binding EditAccountCommand}"/>
    </Grid>
</Page>

Changing Account from a POCO to one that implements the INotifyPropertyChanged allows the UI to refresh the Amount whenever the Edit button is clicked. 将帐户从POCO更改为实现INotifyPropertyChanged帐户后,只要单击“编辑”按钮,UI即可刷新金额。

Alternatively, deleting and reinserting an item will also update the ItemSource , however this is not advisable due to the item will be appended to the end of the collection, and will then need custom sorting logic to say the least. 另外,删除和重新插入项目也会更新ItemSource ,但这是不可取的,因为该项目将附加到集合的末尾,并且至少需要自定义排序逻辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM