我有一个DataGrid,其中列中显示的值并不总是正确更新。
这是定义:
<uic:DataGridControlEx Grid.Row="1"
ReadOnly="True"
Name="m_dgErgaenzungsfelder"
NavigationBehavior ="RowOnly"
SelectionMode="Extended"
AutoCreateColumns="False"
ItemsSource="{Binding Path=ErgaenzungsfelderEntities}"
SelectionChanged="OnDGSelectionChanged" >
<uic:DataGridControlEx.View>
<xc:TableView ColumnStretchMode="Last"
AllowColumnChooser="False"
VerticalGridLineThickness="0"
UseDefaultHeadersFooters="False"
ShowRowSelectorPane="False">
<xc:TableView.FixedHeaders>
<DataTemplate>
<xc:ColumnManagerRow/>
</DataTemplate>
</xc:TableView.FixedHeaders>
<xc:TableView.Theme>
<xc:Office2007SilverTheme />
</xc:TableView.Theme>
</xc:TableView>
</uic:DataGridControlEx.View>
<uic:DataGridControlEx.Columns>
<xc:Column Title="{LocText FGG1:ErgaenzungsfelderResources:ErgaenzungsfelderViewColumnName}"
FieldName="Name" />
<xc:Column Title="{LocText FGG1:ErgaenzungsfelderResources:ErgaenzungsfelderViewColumnType}"
FieldName="ErgaenzungsfeldType" >
<xc:Column.CellContentTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=., Converter={x:Static converters:ErgaenzungsfeldTypeTotextConverter.Instance}}" />
</DataTemplate>
</xc:Column.CellContentTemplate>
</xc:Column>
<xc:Column Title="{LocText FGG1:ErgaenzungsfelderResources:ErgaenzungsfelderViewColumnAuthor}"
FieldName="Author" />
<xc:Column Title="{LocText FGG1:ErgaenzungsfelderResources:ErgaenzungsfelderViewColumnCreationDate}"
FieldName="CreationDate" />
</uic:DataGridControlEx.Columns>
</uic:DataGridControlEx>
DataGridControlEx
执行Xceed DataGridControl但不影响绑定。
后面的代码与网格的ObservableCollection
的定义绑定,早期初始化集合的构造函数和更新项目的方法:
public ObservableCollection<ErgaenzungsfeldEntity> ErgaenzungsfelderEntities { get; private set; }
public ErgaenzungsfelderView() {
ErgaenzungsfelderEntities = new ObservableCollection<ErgaenzungsfeldEntity>();
InitializeComponent();
}
public void ShowErgaenzungsfelder(List<ErgaenzungsfeldEntity> entities) {
ErgaenzungsfelderEntities.Clear();
entities.ForEach(e => ErgaenzungsfelderEntities.Add(e));
//m_dgErgaenzungsfelder.GetBindingExpression(ItemsControl.ItemsSourceProperty).UpdateSource();
}
ErgaenzungsfeldEntity实施INotifyPropertyChanged
并确实通知每次更改的属性更改,例如:
public string Name {
get { return m_name; }
set {
m_name = value;
NotifyPropertyChanged("Name");
}
}
通过GUI更新绑定项目时,所有更改都会正确反映。通过GUI,使用上面提到的ShowErgaenzungsfelder
不会重新加载项目,但绑定项目将作为参考传递。
问题:
我们的服务层可以通知需要重新加载元素的事件。这将调用ShowErgaenzungsfelder
。执行此操作时,添加的实体将显示在网格中,删除的实体将被删除。但是,修改后的实体不会反映Name和ErgaenzungsfeldType字段的变化(这是唯一可以更改的属性)。
例如。更改列排序将触发网格更新并显示正确的值。
对于`ItemsSource,我尝试过更改所有这些属性但没有成功:
ItemsSource="{Binding Path=ErgaenzungsfelderEntities, UpdateSourceTrigger=Explicit, NotifyOnTargetUpdated=True, NotifyOnSourceUpdated=True, Mode=OneWay}"
用
m_dgErgaenzungsfelder.GetBindingExpression(ItemsControl.ItemsSourceProperty).UpdateSource();
中的明确且未注释的ShowErgaenzungsfelder
我很感激任何意见。
答案 0 :(得分:2)
这里有一些心灵调试。
服务层引发的事件未在GUI线程上运行,因此ShowErgaenzungsfelder
函数也不在GUI线程上,也不是通过更改集合引发的事件。 WPF将在非GUI线程上接收这些事件,然后尝试更新GUI,但失败,因为它不是在GUI线程上并且抛出错误。 WPF在生成异常时的行为是中止操作并隐藏异常,因此您什么都看不到。 (在Visual Studio中,您可能会在“输出”面板中看到这些异常;可以选择在那里显示它们。)
要测试这一点,您需要发送GUI线程的更新。您可以按如下方式执行此操作:
public ObservableCollection<ErgaenzungsfeldEntity> ErgaenzungsfelderEntities { get; private set; }
public ErgaenzungsfelderView() {
ErgaenzungsfelderEntities = new ObservableCollection<ErgaenzungsfeldEntity>();
InitializeComponent();
// This will be called on the GUI thread
this.guiContext = SynchronizationContext.Current;
}
private readonly SynchronizationContext guiContext;
public void ShowErgaenzungsfelder(List<ErgaenzungsfeldEntity> entities) {
this.guiContext.Send(this.ShowErgaenzungsfelderOnGuiThread, entities);
}
private void ShowErgaenzungsfelderOnGuiThread(object state) {
List<ErgaenzungsfeldEntity> entities = state as List<ErgaenzungsfeldEntity>;
ErgaenzungsfelderEntities.Clear();
entities.ForEach(e => ErgaenzungsfelderEntities.Add(e));
}