DataGrid组头未在新记录上更新

时间:2018-12-27 06:48:18

标签: wpf wpfdatagrid

我在更新DataGrid分组标题时遇到问题。当我添加或删除一条记录时,除非我重新选择总记录,否则总不会更新,有时甚至编辑记录也不会更新总记录。我根据我运气不好阅读的一些论坛帖子的建议添加了INotifyPropertyChanged,IEditableObject和IsLiveGroupingRequested。我在转换器函数上设置了一个断点,并且我注意到当我添加/删除/编辑记录时它不会触发,直到对表进行排序时才触发。我不确定我在做什么错。

xaml

<Window x:Class="WpfApp2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp2"
        mc:Ignorable="d"
        xmlns:s="clr-namespace:System.ComponentModel;assembly=WindowsBase"
        Title="MainWindow" Height="350" Width="525">

    <Window.Resources>
        <local:Converter1 x:Key="c1"/>
        <CollectionViewSource x:Key="cvs1" Source="{Binding Path=Lines, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
            <CollectionViewSource.GroupDescriptions>
                <PropertyGroupDescription PropertyName="Type"/>
            </CollectionViewSource.GroupDescriptions>
        </CollectionViewSource>
    </Window.Resources>

    <DataGrid Name="_dataGrid1" ItemsSource="{Binding Source={StaticResource cvs1}}">
        <DataGrid.GroupStyle>
            <GroupStyle>
                <GroupStyle.ContainerStyle>
                    <Style TargetType="GroupItem">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="GroupItem">
                                    <StackPanel>
                                        <Grid>
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="*"/>
                                                <ColumnDefinition Width="Auto"/>
                                            </Grid.ColumnDefinitions>
                                            <Label Grid.Column="0" Content="{Binding Path=Name}" Padding="0"/>
                                            <Label Grid.Column="1" Content="{Binding Converter={StaticResource c1}}" Padding="0"/>
                                        </Grid>
                                        <ItemsPresenter/>
                                    </StackPanel>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </GroupStyle.ContainerStyle>
            </GroupStyle>
        </DataGrid.GroupStyle>
    </DataGrid>

</Window>

隐藏代码

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Windows;
using System.Windows.Data;

namespace WpfApp2
{

    public partial class MainWindow : Window
    {

        public MainWindow()
        {

            InitializeComponent();


            Transaction transaction = new Transaction();
            transaction.Lines.Add(new TransactionLine() { Account = "ACCOUNT1", Type = "ACCOUNT", Amount = -41.86 });
            transaction.Lines.Add(new TransactionLine() { Account = "BUDGET1", Type = "BUDGET", Amount = 41.86 });
            transaction.Lines.Add(new TransactionLine() { Account = "CATEGORY1", Type = "CATEGORY", Amount = 41.86 });
            this.DataContext = transaction;

        }

    }

    public class Transaction
    {
        public Transaction()
        {
            this.Lines = new ObservableCollection<TransactionLine>();
        }
        public DateTime Date { get; set; }
        public string Payee { get; set; }
        public ObservableCollection<TransactionLine> Lines { get; set; }
    }
    public class TransactionLine : INotifyPropertyChanged, IEditableObject
    {

        void IEditableObject.BeginEdit()
        {

        }
        void IEditableObject.CancelEdit()
        {

        }
        void IEditableObject.EndEdit()
        {

        }

        public TransactionLine() { }

        private string _account;
        private string _type;
        private double _amount;

        public string Account
        {
            get
            {
                return this._account;
            }
            set
            {
                this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Account"));
                this._account = value;
            }
        }
        public string Type
        {
            get
            {
                return this._type;
            }
            set
            {
                this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Type"));
                this._type = value;
            }
        }
        public double Amount
        {
            get
            {
                return this._amount;
            }
            set
            {
                this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Amount"));
                this._amount = value;
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

    }

    public class Converter1 : IValueConverter
    {

        object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return Math.Round(((CollectionViewGroup)value).Items.Sum(l => ((TransactionLine)l).Amount), 2);
        }
        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }

    }

}

3 个答案:

答案 0 :(得分:1)

在将新值分配给后备字段之前,您要调用PropertyChanged事件。将var EXTRACTED_NAME = Server.MapPath("~/upload/shp/example/"); string shapeFilePath = @"\example.shp"; shapeFilePath = EXTRACTED_NAME + shapeFilePath; Shapefile indexMapFile = Shapefile.OpenFile(shapeFilePath); indexMapFile.Reproject(KnownCoordinateSystems.Geographic.World.WGS1984); 分配给字段后,请确保要调用它。

override fun onBackPressed() {
    if (tabLayout.selectedTabPosition != 0) {
        tabLayout.getTabAt(0)?.select()
    } else {
        super.onBackPressed()
    }
}

答案 1 :(得分:1)

这里的问题是仅在设置了databound属性时才调用转换器。而且,由于您绑定到CollectionViewGroup本身,所以在向Convert添加新项目时将不会调用ObservableCollection<TransactionLine>方法。

您不仅可以绑定到CollectionViewGroup本身,还可以使用MultiBindingIMultiValueConverter实现来绑定到源集合的Count属性:< / p>

public class Converter1 : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        return Math.Round(((CollectionViewGroup)values[0]).Items.Sum(l => ((TransactionLine)l).Amount), 2);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

XAML:

<ControlTemplate TargetType="GroupItem">
    <StackPanel>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <Label Grid.Column="0" Content="{Binding Path=Name}" Padding="0"/>
            <Label Grid.Column="1" Padding="0">
                <Label.Content>
                    <MultiBinding Converter="{StaticResource c1}">
                        <Binding Path="."  />
                        <Binding Path="Items.Count" />
                    </MultiBinding>
                </Label.Content>
            </Label>
        </Grid>
        <ItemsPresenter/>
    </StackPanel>
</ControlTemplate>

答案 2 :(得分:0)

我在这个问题上花了很长时间,发现以下更新组信息(例如组标题)的简便方法是:

        Dispatcher.Invoke(() =>
        {
            DataInfosGrid.Items.Refresh();
        });

您也可以更改DataGrid ItemsSource,但我认为它对您的应用程序来说很重!

再见! ;-D

奥利维尔。