【问题标题】:WPF DataGrid bound grouped items triggered too lateWPF DataGrid 绑定分组项目触发得太晚
【发布时间】:2015-05-28 12:28:17
【问题描述】:

我正在使用 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 的小但非常烦人的问题吗?

【问题讨论】:

  • “Items”属性是否实现了 INotifyPropertyChanged 接口?

标签: c# wpf xaml datagrid


【解决方案1】:

当前,您的绑定设置为在失去焦点时更新绑定属性。要解决此问题,只需将 UpdateSourceTrigger 添加到您的绑定中即可。

Text="{Binding Path=Items, UpdateSourceTrigger=PropertyChanged ...

这将强制INotifyPropertyChanged 在属性更改后立即被调用,因此也会调用转换器。

【讨论】:

  • 谢谢 Mike,但这没有任何效果。我认为触发器应该来自其他地方,因为用户没有更改绑定到“项目”的这个字段。
【解决方案2】:

当用户调整数据网格中的字段时,我发现底层集合处于编辑模式。这些更改保存在内存中的某处,尚未刷新到我的 XAML 中组级别的绑定项集合。要刷新更改并触发 Items 绑定,只需执行提交即可。就我而言,我首先必须将 ICollectionView 转换为 ListCollectionView:

ICollectionView collectionView;
((ListCollectionView)collectionView).CommitEdit();
collectionView.Refresh();

不幸的是,提交时有一个副作用:相关字段离开编辑模式,用户应该点击两次再次进入编辑模式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-18
    • 2023-03-16
    • 1970-01-01
    • 2012-05-17
    • 2015-08-28
    • 2011-02-22
    • 2012-06-24
    相关资源
    最近更新 更多