C# 刷新WPF ItemCollection中的单个项
我有一个绑定到一些XML数据的DataGrid 在XML数据中进行更改时,DataGrid不会刷新以反映这些更改 我解决这个问题的“简单”方法是每次进行更改时调用MyDataGrid.Items.Refresh() 然而,这是落后的,似乎相当低效 如何仅刷新一行而不是整个数据网格?我可以轻松访问DataGridRow以及更改的XmlElement,但我不知道调用什么函数 在这个问题上已经坚持了3-4个小时,并且已经尝试了几十种解决方案,但就是无法让它工作 以下是相关代码 A) 定义样式C# 刷新WPF ItemCollection中的单个项,c#,wpf,datagrid,C#,Wpf,Datagrid,我有一个绑定到一些XML数据的DataGrid 在XML数据中进行更改时,DataGrid不会刷新以反映这些更改 我解决这个问题的“简单”方法是每次进行更改时调用MyDataGrid.Items.Refresh() 然而,这是落后的,似乎相当低效 如何仅刷新一行而不是整个数据网格?我可以轻松访问DataGridRow以及更改的XmlElement,但我不知道调用什么函数 在这个问题上已经坚持了3-4个小时,并且已经尝试了几十种解决方案,但就是无法让它工作 以下是相关代码 A) 定义样式
<!-- Field Value Style -->
<local:FieldValueConverter x:Key="FieldValueConverter"/>
<local:Node x:Key="Node"/>
<Style x:Key="fieldValueStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Text" Value="{Binding ., Converter={StaticResource FieldValueConverter}}"/>
<Setter Property="KeyboardNavigation.IsTabStop" Value="False"/>
<Setter Property="Focusable" Value="False"/>
</Style>
B) 定义数据网格
<DataGrid x:Name="FieldPanelDataGrid" DockPanel.Dock="Left"
AutoGenerateColumns="False"
DataContext="{Binding ElementName=ObjectPanelListBox, Path=SelectedItem}"
ItemsSource="{Binding}"
IsSynchronizedWithCurrentItem="True"
IsReadOnly="True"
CanUserResizeRows="False"
CanUserResizeColumns="True"
KeyboardNavigation.IsTabStop="False"
Visibility="Visible"
SelectionMode="Single">
<DataGrid.Resources>
<Style TargetType="DataGridRow">
<EventSetter Event="MouseDoubleClick" Handler="FieldCell_MouseDoubleClick"/>
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="FieldCell_PreviewMouseLeftButonDown"></EventSetter>
<EventSetter Event="PreviewKeyDown" Handler="FieldCell_PreviewKeyDown"></EventSetter>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn x:Name="FieldName" Header="Name" CanUserSort="False" ElementStyle="{StaticResource fieldNameStyle}"/>
<DataGridTextColumn x:Name="FieldValue" Header="Value" Width="*" ElementStyle="{StaticResource fieldValueStyle}"/>
</DataGrid.Columns>
</DataGrid>
我建议使用ObservableCollection作为ItemSource,ObservableCollection中的条目必须实现INotifyPropertyChanged。然后,如果行发生更改,则ObservableCollection将通知您的UI,并且它将更新 例如: 您的入门课程:
public class MyXmlObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string fieldName;
public string FieldName
{
get { return fieldName; }
set
{
fieldName = value;
NotifyPropertyChanged("FieldName");
}
}
NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
用户控件(视图模型、控制器或代码隐藏)的代码:
publicobservablecollection MyCollection{get;set;}
正如我在xaml中提到的,您只需将集合绑定到ItemsSource
<DataGrid ItemsSource="{Binding MyCollection}" .../>
现在,只有正在更改的项才能得到更新。是否可以从源集合中删除已更改的XmlElement,然后将其重新插入到相同的位置?它可以工作..可能首先向我们展示您读取XML并填充数据网格的代码。此外,对XML(文件)的更改是否在应用程序外部?如果是这样,也许您可以连接一个filesystemwatcher来监视您的xml文件,并相应地更新您的数据网格。@h.alex:好主意。我得到一个错误,大意是“在使用ItemsSource时操作无效。请改为使用ItemsControl.ItemsSource访问和修改元素”。编程失败:我用一些代码更新了原来的帖子。更改在应用程序中。查看是否有帮助。@h.alex:我查看了帖子;“列表”和“可观察收集”与我的问题有什么关系?我应该实现自定义DataGrid类型还是自定义DatGridRow类型?我可能缺少一些明显的东西,但是当我将DataGrid的ItemSource从{Binding}更改为{Binding MyCollection}时,我的所有项目都会消失。这取决于您的UserControls DataContext。您必须将集合放入表示UserControls DataContext的类中。例如,如果它是UserControl本身的代码,请尝试设置DataContext=this;我不确定这是否有效,因为我已经在XAML中将DataContext设置为“{Binding ElementName=ObjectPanelListBox,Path=SelectedItem}”
<DataGrid ItemsSource="{Binding MyCollection}" .../>