【问题标题】:Samples on Live Updating Data Grid WPF实时更新数据网格 WPF 示例
【发布时间】:2012-03-01 14:48:01
【问题描述】:

能否请您提供一些 WPF 中 DataGrid 更新的示例。

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

下面是代码sn-p。

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 集合时,没有发生实时更新。

【问题讨论】:

  • 为您更新了我的答案。希望对你有帮助

标签: wpf datagrid datagridview wpfdatagrid


【解决方案1】:

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

【讨论】:

  • 嗨 Martin,我使用的是 MVVM 模式,如果我没记错的话,我的模型有一个集合,它通过 ItemsSource 绑定到 DataGrid。要引发 CollectionChanged 事件我应该如何处理?
  • 在 WPF 中,您可以使用 ObservableCollection 来存储您的项目:msdn.microsoft.com/en-us/library/ms668604.aspx(或任何实现 INotifyCollectionChanged 的集合)。
【解决方案2】:

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

请注意,这将适用于添加或删除列表中的项目,但如果您自己更改项目的属性并想要更新ObservableCollection,则需要有一个ViewModelsObservableCollection,它们正在实现INotifyPropertyChanged 在每个属性上。


编辑

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

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

这是我做的代码:

 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

请注意,INotifyPropertyChanged 成员区域实现了 PropertyChanged 事件,而调试辅助区域仅检查 OnPropertyChanged 处理程序中指定的属性是否确实存在。


这里是 xaml:

 <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>

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


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

 public class RelayCommand : ICommand
{

    #region Private Accessor Fields

    /// <summary>
    /// A boolean function that contains the code to enable/disable the command and the associated UI elements.
    /// </summary>
    private readonly Func<object, bool> _canExecute = null;

    /// <summary>
    /// A generic delegate that will contain the code to execute.
    /// </summary>
    private readonly Action<object> _executeAction = null;

    #endregion  //Private Accessor Fields


    #region Constructor

    /// <summary>
    /// Initializes a new instance of the RelayCommannd class
    /// </summary>
    /// <param name="executeAction">The execute action.</param>
    /// <param name="canExecute">The can execute.</param>
    public RelayCommand(Action<object> executeAction, Func<object, bool> canExecute)
    {
        this._executeAction = executeAction;
        this._canExecute = canExecute;
    }

    #endregion

    //Modified on 15 August 2011. CanExecuteChanged
    #region Implementation of ICommand

    /// <summary>
    /// Occurs when changes occur that affect whether or not the command should execute.
    /// </summary>
    public event EventHandler CanExecuteChanged
    {
        //RequerySuggested occurs when the CommandManager detects conditions that might
        //change the ability of a command to execute. 
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    /// <summary>
    /// Defines the method that determines whether the command can execute in its current state.
    /// </summary>
    /// <param name="parameter">Data used by the command. If the command does not require data to be passed, 
    /// this object can be null.</param>
    /// <returns>true if this command can be executed; otherwise, false.</returns>
    public bool CanExecute(object parameter)
    {
        if (this._canExecute == null)
        {
            return true;
        }
        return this._canExecute(parameter);
    }

    /// <summary>
    /// Defines the method to be called when the command is invoked.
    /// </summary>
    /// <param name="parameter">Data used by the command. If the command does not require data to be passed, 
    /// this object can be set to null</param>
    public void Execute(object parameter)
    {
        if (this._executeAction != null)
        {
            this._executeAction(parameter);
        }
    }

    #endregion

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-06
    • 1970-01-01
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    相关资源
    最近更新 更多