C# 为什么我既不使用可观察集合也不调用Items.Refresh()就可以更新DataGrid itemsource?

C# 为什么我既不使用可观察集合也不调用Items.Refresh()就可以更新DataGrid itemsource?,c#,wpf,data-binding,C#,Wpf,Data Binding,标题是正确的。我想知道为什么会这样: 我有一个datagrid,其ItemsSource绑定到类型为List的属性。在代码隐藏中,我实例化一个新的列表,使用循环填充它,并引发我的属性更改事件。这将导致数据网格被更新。然而,我的印象是我应该使用可观察收集而不是列表,否则数据网格将不会更新。。。但事实确实如此 以下是相关代码: <DataGrid x:Name="dgv_Items" Grid.Row="3" Grid

标题是正确的。我想知道为什么会这样:

我有一个datagrid,其ItemsSource绑定到类型为
List
的属性。在代码隐藏中,我实例化一个新的
列表
,使用循环填充它,并引发我的
属性更改
事件。这将导致数据网格被更新。然而,我的印象是我应该使用
可观察收集
而不是
列表
,否则数据网格将不会更新。。。但事实确实如此

以下是相关代码:

<DataGrid x:Name="dgv_Items"
         Grid.Row="3"
         Grid.ColumnSpan="19"
         Grid.RowSpan="4"
         ItemsSource="{Binding ITEMS}"
         FontWeight="Bold"
         GridLinesVisibility="None"
         IsReadOnly="True"
         SelectedItem="{Binding SelectedItemI, Mode=TwoWay}"
         SelectionMode="Single" SelectionUnit="FullRow">
  <DataGrid.RowStyle>
    <Style TargetType="DataGridRow">
      <Style.Triggers>
        <DataTrigger Binding="{Binding Param, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Value="Conferido">
          <Setter Property="Foreground" Value="Green"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding Param, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Value="Achado">
          <Setter Property="Foreground" Value="Orange"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding Param, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Value="Inexistente">
          <Setter Property="Foreground" Value="Red"/>
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </DataGrid.RowStyle>
</DataGrid>

公共列表项{get;set;}
公共异步任务重要性(字符串路径)
{
项目=新列表();
foreach(TNFE.infNFe.det中的var det)
{
ITEMS.Add(新的ItemImportado()
{
CodFornec=det.prod.cProd,
DescFornec=det.prod.xProd,
Quant=decimal.Parse(det.prod.qCom,CultureInfo.InvariantCulture),
VlrUnit=decimal.Parse(det.prod.vUnCom,CultureInfo.InvariantCulture),
NItem=int.Parse(det.NItem),
Detalhamento=det
});
}
OnPropertyChanged(空);
}

DataGrid
没有显式的
UpdateSourceTrigger
,我也没有调用
dgv.Items.Refresh()
。它为什么会更新数据网格的项目?样式绑定是否也会更新数据网格的项?

UI会更新,因为您在为集合属性分配新值并向其添加项后触发PropertyChanged事件


与其每次都创建新的集合实例,不如使用只读ObservableCollection属性:

public ObservableCollection<ItemImportado> Items { get; }
    = new ObservableCollection<ItemImportado>();

public void ImportaNFE()
{
    Items.Clear();

    foreach (var det in TNFE.infNFe.det)
    {
        Items.Add(new ItemImportado
        {
            ...
        });
    }
}
publicobservableCollection项{get;}
=新的ObservableCollection();
公共无效重要事件()
{
Items.Clear();
foreach(TNFE.infNFe.det中的var det)
{
项目。添加(新项目导入到
{
...
});
}
}

您提出的属性已更改,binding重新评估了您的列表,这一切似乎与预期相符。毕竟,这就是为什么要为绑定到UI的属性引发property changed。因此,当使用ObservableCollection时,我不需要调用PropertyChanged?不,它有自己的事件,在修改它时会引发这些事件。使用当前方法-重新评估整个列表。使用ObservableCollection-例如,如果您在那里添加了一个项目,那么只处理该项目(为其创建UI元素等等),并且
OnPropertyChanged(null)
应该是
OnPropertyChanged(nameof(ITEMS))
我知道,但在您的问题中没有表明您也知道它。在这个问题的背景下,这是没有意义的。还请注意,将ObservableCollections用作只读属性是一种很好的做法。您不需要触发PropertyChanged事件。只需创建一次集合,如有必要,只需在添加新项目之前清除它。我可以将ObservableCollections与EF核心模型一起使用吗?当然,为什么不?我在创建外部一对多EF关系时被教导,我应该只使用列表。那么我将把列表更改为observablecollections。非常感谢你!!