【问题标题】:DataGrid and ObservableCollection Biding not updating at RuntimeDataGrid 和 ObservableCollection 绑定在运行时不更新
【发布时间】:2017-11-21 17:50:29
【问题描述】:

背景:

我有一个DataGrid,其中填充了ObservableCollectionObservableCollection设计时不会包含任何项目。

我在 运行时 使用 TextBox 的内容更新集合,循环通过导入的 .Text/.CSV 文件并粘贴剪贴板中的文本。 正如您将在下面看到的,我在 XAML 中绑定集合并在 DataGrid 中指定列详细信息。

集合由要显示的数据的类启动。

我可以通过单击按钮直接将项目添加到DataGrid,它会出现,但是当我将它添加到ObservableCollection 时,它不会显示,尽管它已添加到集合中。

XAML:

<DataGrid x:Name="SysCheck_DataGrid" 
          BorderBrush="Gray"
          AutoGenerateColumns="False"
          ItemsSource="{Binding Path=_SysCheckDataGridSource, Mode=TwoWay}"
          SelectionMode="Extended"
          SelectionUnit="FullRow"
          CanUserDeleteRows="True"
          CanUserReorderColumns="True"
          AlternatingRowBackground="Gainsboro"
          AlternationCount="2">
  <DataGrid.Columns>
    <DataGridTextColumn Header="Hostname" Binding="{Binding Hostname}"/>
    <DataGridTextColumn Header="IP Address" Binding="{Binding IPAddress}"/>
    <DataGridTextColumn Header="Online" Binding="{Binding Online}"/>
    <DataGridTextColumn Header="Last Restarted" Binding="{Binding LastRestarted}"/>
    <DataGridTextColumn Header="OS" Binding="{Binding OS}"/>
  </DataGrid.Columns>
</DataGrid>

C# 背后的代码:

private void SysCheck_Add_Button_Click(object sender, RoutedEventArgs e)
{
    if (!string.IsNullOrWhiteSpace(SysCheck_Manuel_Add_TB.Text))
    {
        var item = _SysCheckDataGridSource.SingleOrDefault(
            i => i.Hostname == SysCheck_Manuel_Add_TB.Text);

        if (item == null)
        {
            SysCheck_DataGrid.Items.Add(new SystemCheckingNormal()
                { Hostname = SysCheck_Manuel_Add_TB.Text });

            SystemChecking_Log.Text += Environment.NewLine + SysCheck_Manuel_Add_TB.Text
                + " was added to DataGrid " + "There are "
                + _SysCheckDataGridSource.Count + " items in the list";

            SysCheck_Manuel_Add_TB.Clear();
        }
        else
        {
            SystemChecking_Log.Text += Environment.NewLine + SysCheck_Manuel_Add_TB.Text
                + " Is already in the DataGrid " + "There are "
                + _SysCheckDataGridSource.Count + " items in the list";

            SysCheck_Manuel_Add_TB.Clear();
        }
    }
}

类代码:

public class SystemCheckingNormal
{
    public string Hostname { get; set; }
    public string IPAddress { get; set; }
    public string Online { get; set; }
    public string LastRestarted { get; set; }
    public string OS { get; set; }
}

回答问题:

mm8 问:

您的ObservableCollection 在哪里以及您在哪里以及如何向其中添加项目?

答案:

public ObservableCollection<SystemCheckingNormal> _SysCheckDataGridSource;

MainWindow 类中

和:

_SysCheckDataGridSource = new ObservableCollection<SystemCheckingNormal>();

MainWindow() 构造函数中。

到目前为止,我在Click 事件中添加到集合中(在上面的代码中):

SysCheck_DataGrid.Items.Add(new SystemCheckingNormal()
    { Hostname = SysCheck_Manuel_Add_TB.Text });

【问题讨论】:

  • 您的 ObservableCollection 在哪里以及您在哪里以及如何向其中添加项目?
  • 使用前请阅读Binding的属性。 Mode=TwoWayItemsSource 绑定没有意义。
  • @mm8 请看我原问题的回复
  • @NigelTatschner:请看我的回答。 _SysCheckDataGridSource 是一个字段。它必须是一个财产。添加 {get;放; } 部分。

标签: c# wpf xaml datagrid observablecollection


【解决方案1】:

您的 ObservableCollection 属性必须是公共属性。在您的情况下,它应该看起来像

public ObservableCollection<SystemCheckingNormal> _SysCheckDataGridSource {get;set;}

DataGrid 的 DataContext 必须是具有此属性的实例。

【讨论】:

    【解决方案2】:

    _SysCheckDataGridSource 是一个字段

    public ObservableCollection<SystemCheckingNormal> _SysCheckDataGridSource; 
    

    您只能绑定到 WPF 中的公共属性(而不是字段):

    public ObservableCollection<SystemCheckingNormal> SysCheckDataGridSource { get; set; }
    

    还请注意,您应该从属性名称中删除下划线(记住也要在 XAML 标记中修改它)。

    还需要设置视图的DataContext

    public MainWindow()
    {
        InitializeComponent();
        SysCheckDataGridSource = new ObservableCollection<SystemCheckingNormal>();
        DataContext = this;
    }
    

    【讨论】:

    • 谢谢你,我已经添加了更改,但在 DataGrid 中仍然没有得到任何东西,我将 ADD 更改为:SysCheckDataGridSource.Add(new SystemCheckingNormal() { Hostname = SysCheck_Manuel_Add_TB.文本});
    • 你是否在某处设置了视图的DataContext?
    • 不,我是否将 ItemsSource="{Binding Path=SysCheckDataGridSource}" 更改为其他内容?
    • 我可能在这里遗漏了一些东西,我是 wpf 和 c# 的新手,这是源代码:github.com/ntatschner/NT-Tools
    • 您缺少设置 DataContext。查看我的编辑。
    【解决方案3】:

    你的类需要像这样实现 INotifyPropertyChanged

    public class SystemCheckingNormal : INotifyPropertyChanged
    {
        private string hostname ;
        private string iPAddress ;
        private string online ;
        private string lastRestarted ;
        private string oS ;
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }
        Public string Hostname
        {
           get{return hostname;}
           set
           {
              if(hostname != value)
                {
                  hostname = value;
                  OnPropertyChanged("Hostname");
                }
           }
        }
    }
    

    对所有其他变量做同样的事情(我只写了主机名让你理解)

    【讨论】:

    • 仅当您打算在运行时动态更改单个 SystemCheckingNormal 对象的属性值时才需要这样做。它与 ObservableCollection 无关。
    • 谢谢你,我打算在这部分工作后改变:) @ Daniel
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-15
    • 2014-03-07
    • 2017-08-31
    • 2021-10-20
    • 2014-02-01
    • 1970-01-01
    相关资源
    最近更新 更多