WPF DataGrid 使用 ObservableCollection 源自动刷新

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17423165/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:07:52  来源:igfitidea点击:

WPF DataGrid auto-refresh with ObservableCollection source

c#wpf

提问by Wonder

I'm new to WPF and I can't get my grid to auto-refresh when some property changes. Only thing I achieved - auto-refresh on element adding.

我是 WPF 的新手,当某些属性发生变化时,我无法让我的网格自动刷新。我唯一实现的 - 添加元素时自动刷新。

Here is my code:

这是我的代码:

public partial class MainWindow : Window
{
    private Model model;

    public MainWindow()
    {
        InitializeComponent();
        model = new Model();
        MyGrid.ItemsSource = model.Content;
    }

    private void MyButton_Click(object sender, RoutedEventArgs e)
    {
        MyGrid.Items.Refresh();
    }
}

public class Model
{
    public ObservableCollection<Single> Content;
    private Random r;
    private Action action;
    private static object _syncLock = new object();

    public Model()
    {
        Content = new ObservableCollection<Single>();
        r = new Random(); 
        action = new Action(process);
        action.BeginInvoke(null,null);
        BindingOperations.EnableCollectionSynchronization(Content, _syncLock);          
    }

    private void process()
    {
        while (true)
        {
            Content.Add(new Single { Name = "name" });
            Content[r.Next(0,Content.Count())].Name = "rename" + r.Next(1,100);
            Thread.Sleep(1000);
        }
    }
}

public class Single : INotifyPropertyChanged
{
    private string name;
    public string Name 
    {
        get { return name; }
        set 
        {
            name = value;
            RaisePropertyChanged(Name);
        } 
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

回答by JSJ

Make you model variable notifyable and this will work for you.

让您对模型变量进行通知,这对您有用。

Try Changing the above code with.

尝试更改上面的代码。

    public partial class Window1 : Window, INotifyPropertyChanged
{
    private Model model;

    public Model ModelData
    {
        get { return model; }
        set
        {
            model = value;
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs("ModelData"));
        }
    }

    public Window1()
    {
        this.InitializeComponent();
            ModelData = new Model();          
        MyGrid.ItemsSource = ModelData.Content;

    }

    public event PropertyChangedEventHandler PropertyChanged;
}
public class Model
{
    public ObservableCollection<Single> Content { get; set; }

    private Random r;

    private static object _syncLock = new object();

    public Model()
    {
        Content = new ObservableCollection<Single>();
        Content.Add(new Single { Name = "name" });
        r = new Random();

        // BindingOperations.EnableCollectionSynchronization(Content, _syncLock);
        DispatcherTimer t = new DispatcherTimer();
        t.Interval = new TimeSpan(2000);
        t.Tick += new EventHandler(t_Tick);
        t.Start();
    }

    void t_Tick(object sender, EventArgs e)
    {
        App.Current.Dispatcher.BeginInvoke(new Action(() =>
        {
            if (Content.Count <= 100)
                Content.Add(new Single { Name = "name" });
            Content[r.Next(0, Content.Count())].Name = "rename" + r.Next(1, 100);

        }));
    }


}
public class Single : INotifyPropertyChanged
{
    private string name;
    public string Name
    {
        get { return name; }
        set
        {
            name = value;
            RaisePropertyChanged("Name");
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Xaml

xml

 <DataGrid Name="MyGrid"  AutoGenerateColumns="False"  Margin="246,175,0,0">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Names" Binding="{Binding Name }" />
            </DataGrid.Columns>
        </DataGrid>

回答by Wonder

The problem was here:

问题出在这里:

public string Name
{
    get { return name; }
    set
    {
        name = value;
        RaisePropertyChanged(Name);
    }
}

Had to use

不得不使用

RaisePropertyChanged("Name");

Simple and stupid..

简单又蠢。。