实时更新数据网格WPF上的示例

时间:2012-03-01 14:48:01

标签: wpf datagrid datagridview wpfdatagrid

请您提供一些WPF中DataGrid更新的样本。

我正在尝试编写一个应用程序,它将定期更新LIST并且我想使用WPF在DataGrid上显示。

以下是代码段。

MainWindow.XAMl

Model _model = new Model();
  private void Window_Loaded(object sender, RoutedEventArgs e)
        {

            this.DataContext = _model;
        }

DataGrid Xaml

 <DataGrid
            Height="214" 
            HorizontalAlignment="Left" 
            Margin="12,135,0,0" 
            Name="resultDataGrid" 
            VerticalAlignment="Top"
            Width="720"   
            ItemsSource="{Binding Path=Results, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
         />

我正在更新结果的代码。

public class Model : INotifyPropertyChanged
    {
     ObservableCollection<Result> _results  = new ObservableCollection<Result>();

public void X()
{
     foreach (var file in Files)
                {
                    _results.Add(new Result() { File = file, Status = "passsed" });
                  }
}

 public ObservableCollection<Result> Results
        {
            get { return _results; }
            set { _results = value; OnPropertyChanged("Results"); }
        }
}

当我添加到_results集合时,实时更新没有发生。

2 个答案:

答案 0 :(得分:0)

使用数据绑定(通过将DataGrid.ItemsSource绑定到您的项目集合)并记住在项目更新时触发INotifyPropertyChanged.PropertyChanged。或者,如果它是项目的集合而不是改变火灾的单个项目INotifyCollectionChanged.CollectionChanged。显然,你需要数据绑定到实现这些接口的类才能工作。

答案 1 :(得分:0)

尝试使用Observable Collection而不是普通列表。该集合已经实现了INotifyCollectionChanged。

请注意,这可用于添加或删除列表中的项目,但如果您自己更改项目的属性并想要更新ObservableCollection,则需要ObservableCollection {{1}在每个属性上实现ViewModels


修改

这可能是一个愚蠢的问题,但你实际上在哪里调用x方法?我完全复制了你的代码,创建了我自己的Result类,并实现了INotifyPropertyChanged并创建了一个implementation of the RelayCommand pattern,将其绑定到按钮的命令,这一切都有效。当我单击按钮时,数据网格会发生变化。

我能想到的是你实际上没有实现INotifyPropertyChanged,或者你没有运行x方法。

这是我做的代码:

INotifyPropertyChanged

请注意,INotifyPropertyChanged Members区域实现了PropertyChanged事件,而Debugging aids区域只检查OnPropertyChanged处理程序中指定的属性是否确实存在。


这是xaml:

 public class Model : INotifyPropertyChanged
{
    ObservableCollection<Result> _results = new ObservableCollection<Result>();
    private List<string> Files;


    public void X()
    {
        foreach (var file in Files)
        {
            _results.Add(new Result() { File = file, Status = "passsed" });
        }

        _results.Add(new Result() { File = DateTime.Now.ToString(), Status = "passed" });
    }

    public ObservableCollection<Result> Results
    {
        get { return _results; }
        set { _results = value; OnPropertyChanged("Results"); }
    }
    public ICommand XCmd { get; protected set; }


    private void InitializeCommands()
    {
        this.XCmd = new RelayCommand((param) => { this.X(); },
                                          (param) => { return true; });

    }

    public Model()
    {
        Files = new List<string>();
        Files.Add("ONE");
        Files.Add("TWO");
        Files.Add("THREE");
        Files.Add("FOUR");

        _results.Add(new Result() { File = "ZERO", Status = "Pending" });
        _results.Add(new Result() { File = DateTime.Now.ToString(), Status = "Pending" });
        InitializeCommands();
    }

    #region INotifyPropertyChanged Members

    /// <summary>
    /// Raised when a property on this object has a new value.
    /// </summary>
    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>
    /// Raises this object's PropertyChanged event.
    /// </summary>
    /// <param name="propertyName">The property that has a new value.</param>
    protected virtual void OnPropertyChanged(string propertyName)
    {
        this.VerifyPropertyName(propertyName);

        PropertyChangedEventHandler handler = this.PropertyChanged;
        if (handler != null)
        {
            var e = new PropertyChangedEventArgs(propertyName);
            handler(this, e);
        }
    }

    #endregion // INotifyPropertyChanged Members

    #region Debugging Aides

    /// <summary>
    /// Warns the developer if this object does not have
    /// a public property with the specified name. This 
    /// method does not exist in a Release build.
    /// </summary>
    [Conditional("DEBUG")]
    [DebuggerStepThrough]
    public void VerifyPropertyName(string propertyName)
    {
        // Verify that the property name matches a real,  
        // public, instance property on this object.
        if (TypeDescriptor.GetProperties(this)[propertyName] == null)
        {
            string msg = "Invalid property name: " + propertyName;

            if (this.ThrowOnInvalidPropertyName)
                throw new Exception(msg);
            else
                Debug.Fail(msg);
        }
    }

    /// <summary>
    /// Returns whether an exception is thrown, or if a Debug.Fail() is used
    /// when an invalid property name is passed to the VerifyPropertyName method.
    /// The default value is false, but subclasses used by unit tests might 
    /// override this property's getter to return true.
    /// </summary>
    protected virtual bool ThrowOnInvalidPropertyName { get; private set; }

    #endregion // Debugging Aides

我知道它并不漂亮,但你可以随意设计它


这是我之前链接过你的relaycommand实现:

 <Grid>
    <Grid.RowDefinitions>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
    </Grid.RowDefinitions>
    <DataGrid
        HorizontalAlignment="Stretch" 
        Name="resultDataGrid" 
        VerticalAlignment="Stretch"
        ItemsSource="{Binding Path=Results, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
     />

    <Button Grid.Row="2" Command="{Binding XCmd}" Margin="5,5,5,5">click</Button>
</Grid>

如果这不起作用,您将不得不向我展示更多代码,因为我真的不知道为什么它不起作用。