我正在使用WPF DataGrid来显示已经分为两级的数据。大多数XAML /代码都基于https://msdn.microsoft.com/en-us/library/ff407126%28v=vs.110%29.aspx上的MSDN示例。
除了这个例子,我还在每个第二级分组下面添加了一个摘要行来进行一些求和。用户能够更改影响一个或多个汇总的行。每次用户进行更改时,应直接重新评估摘要,以便查看更改的结果。
除摘要行更新外,所有功能都可以正常工作。在用户更新网格内的字段之后,不会重新评估总和。实际上,并不触发求和的绑定来调用转换器进行新的求和。我发现通过单击鼠标将焦点更改为DataGrid的另一部分(在更改的行之外!)时,触发器就会出现。
让我澄清一下我的XAML /代码的相关部分......
为了获取属于该组的行,我绑定到Items属性并将它们发送到转换器。在XAML中,此摘要行显示在元素的元素中:
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="1*" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"
Text="{Binding Path=Name}"
FontWeight="Bold" FontSize="13"
TextAlignment="Left" Margin="5,0,0,0"/>
<ItemsPresenter Grid.Row="1" />
<!-- Grid that represents the summary row -->
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- for simplicity, only one summation field-->
<!-- This binding isn't updated unless I change focus somewhere outside the edited row -->
<TextBlock Grid.Column="0" Margin="0,0,-2,0" HorizontalAlignment="Right" FontWeight="Bold" Text="{Binding Path=Items,
Converter={StaticResource decimalGroupSumConverter}, ConverterParameter=AmountPerYear}"/>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
调用求和的转换器:
public class DecimalGroupSumConverter : IValueConverter
{
public object Convert(object value, System.Type targetType,
object parameter,
System.Globalization.CultureInfo culture)
{
if (null == value)
return "null";
ReadOnlyObservableCollection<object> items =
(ReadOnlyObservableCollection<object>)value;
if (parameter.ToString() == "AmountPerYear")
{
var sum = (from i in items
select ((ObservableCalculatedActivity)i).AmountPerYear).Sum();
return string.Format("{0:c}", sum);
}
else
{
return null;
}
}
public object ConvertBack(object value, System.Type targetType,
object parameter,
System.Globalization.CultureInfo culture)
{
throw new System.NotImplementedException();
}
}
下一个列表显示我试图强制UI更新但没有任何成功:
请帮助我解决有关更新UI的这个微小但非常烦人的问题吗?
答案 0 :(得分:0)
目前,您的绑定设置为在焦点丢失时更新绑定属性。要解决此问题,只需将UpdateSourceTrigger
添加到绑定中即可。
Text="{Binding Path=Items, UpdateSourceTrigger=PropertyChanged ...
一旦属性发生变化,这将强制调用INotifyPropertyChanged
,因此也会调用Converter。
答案 1 :(得分:0)
我发现当用户调整数据网格中的字段时,底层集合处于编辑模式。这些更改保留在内存中的某个位置,并且尚未刷新到我的XAML中组级别的绑定Items集合。要刷新更改并触发Items绑定,只需执行提交。在我的情况下,我首先必须将ICollectionView转换为ListCollectionView:
ICollectionView collectionView;
((ListCollectionView)collectionView).CommitEdit();
collectionView.Refresh();
不幸的是,提交时会产生副作用:相关字段离开编辑模式,用户应再次点击两次以进入编辑模式。