其他一些更改时,DataGrid中的从属列也不会更改(WPF C#) [英] Dependent Column in DataGrid not change when some other changes ( WPF C#)

查看:54
本文介绍了其他一些更改时,DataGrid中的从属列也不会更改(WPF C#)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序中有一堆 Order ,我想在datagrid中显示它们并就地编辑它们的属性。有一个名为 Order 的类,其权重属性取决于 Item.Weight Order.Count 。在 ObservableCollection< Order>所指向的数据网格中订单已绑定,我想更改行。 城市项目的值正在更改,但重量不变当项目计数更改时,UI会更新。

I have bunch of Orders in my application which i want to show in datagrid and edit their attributes inplace. There is a class named Order which weight attribute depends on Item.Weight and Order.Count. In the datagrid to which ObservableCollection<Order> Orders is bound, I want to change rows in place. The City and Item values are changing but Weight does not update in UI when Item or Count change.

--MyViewModel

--MyViewModel

public class Order : INotifyPropertyChanged
{
    private int _OrderId;

    public int OrderId
    {
        get { return _OrderId; }
        set
        {
            _OrderId = value;
            RaiseProperChanged();
        }
    }
    private City _City;
    public City City
    {
        get { return _City; }
        set
        {
            _City = value;
            RaiseProperChanged();
        }
    }
    private Item _Item;
    public Item Item
    {
        get { return _Item; }
        set
        {
            _Item = value;
            RaiseProperChanged();
        }
    }
    private int _Count;
    public int Count
    {
        get { return _Count; }
        set
        {
            _Count = value;
            RaiseProperChanged();
        }
    }
    private int _Weight;
    public int Weight
    {
        get { return _Weight; }
        set
        {
            _Weight = value;
            RaiseProperChanged();
        }
    }
    public static ObservableCollection<Order> GetOrders()
    {
        var Orders = new ObservableCollection<Order>();
        return Orders;
    }
    public DateTime DateOfOrder { set; get; }
    public Order()
    {

    }
    public Order(int _id, City _cty, Item _itm, int _count)
    {
        OrderId = _id;
        _City = _cty;
        _Item = _itm;
        Count = _count;
        Weight = _itm.Weight * _count;
        DateOfOrder = DateTime.Now;
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void RaiseProperChanged([CallerMemberName] string caller = "")
    {

        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(caller));
        }
    }
}

}

-我的视图

<DataGrid x:Name="Orders"
              FlowDirection="RightToLeft"
              Margin="20,0,20,0"
              AutoGenerateColumns="False"
              DataGridCell.Selected="DataGrid_GotFocus"
              CanUserAddRows="True"
              SelectionUnit="FullRow"
              Height="250">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding OrderId, 
                    Mode=TwoWay, 
                    UpdateSourceTrigger=PropertyChanged}"
                                Header="ردیف"
                                FontFamily="{StaticResource BLotus}"
                                Width="70"
                                IsReadOnly="True"/>

            <DataGridComboBoxColumn SelectedItemBinding="{Binding City, 
                    Mode=TwoWay, 
                    UpdateSourceTrigger=PropertyChanged}"
                                    DisplayMemberPath="Name"
                                    x:Name="citytoadd"
                                    Header="شهر"
                                    Width="150"
                                    />
            <DataGridComboBoxColumn Header="محصول"
                                    x:Name="itemtoadd"
                                    SelectedItemBinding="{Binding Item, 
                    Mode=TwoWay, 
                    UpdateSourceTrigger=PropertyChanged}"
                                    DisplayMemberPath="Name"
                                    Width="350" />
            <DataGridTextColumn Binding="{Binding Count, 
                    Mode=TwoWay, 
                    UpdateSourceTrigger=PropertyChanged}"
                                Header="تعداد"
                                Width="75"
                                />
            <DataGridTextColumn Binding="{Binding Weight, 
                    Mode=TwoWay, 
                    UpdateSourceTrigger=PropertyChanged}"
                                Header="وزن"
                                Width="100"
                                IsReadOnly="True"/>
        </DataGrid.Columns>
    </DataGrid>

例如:当我在datagrid中编辑一行时,我想更新整个属性,但是在此情况下,我可以更改项目的项目计数城市 订单,但重量不会更新。

For example : when i edit a row in datagrid i want to update the entire attributes , but in this case i can change Item, Count and City of a Order but weight doesnt update.

推荐答案

因为要显示根据其他属性计算出的 Weight 值,您应该更改代码的以下部分:

Since you want to display a calculated Weight value based on other properties, you should change the following parts of your code:

使绑定一个

<DataGridTextColumn Binding="{Binding Weight, Mode=OneWay}"
                    Header="وزن"
                    Width="100"
                    IsReadOnly="True"/>

将该属性写为仅获取计算。

Write the property as get-only calculation.

public int Weight
{
    get { return Item.Weight * Count; } // TODO: adjust if Item can be null
}

通知相关的更改计算的源属性。如果 Item.Weight 在一个项目实例中可以更改,则您需要进行其他处理。

Notify for dependent changes in the source properties of your calculation. If Item.Weight could change within an item instance, you need additional handling.

private Item _Item;
public Item Item
{
    get { return _Item; }
    set
    {
        _Item = value;
        RaiseProperChanged();
        RaiseProperChanged(nameof(Weight));
    }
}
private int _Count;
public int Count
{
    get { return _Count; }
    set
    {
        _Count = value;
        RaiseProperChanged();
        RaiseProperChanged(nameof(Weight));
    }
}

删除所有访问的内容重量的二传手(例如在构造函数中)。

Remove everything that accesses the Weight setter (for example in constructor).

有关计算所得属性,请参见以下最小工作示例。在这种情况下,我依赖于自动生成的列,但手写列也应如此。

See the following minimal working example for a calculated property. I rely on auto-generated columns in this case, but the same should be possible with hand written columns.

<Window
    ... your default generated window class, nothing special ... >
    <Grid x:Name="grid1">
        <DataGrid ItemsSource="{Binding}"/>
    </Grid>
</Window>

具有依赖属性已计算的Viewmodel项类型定义:

Viewmodel itemtype definition with dependent property Calculated:

public class ExampleItemViewModel : INotifyPropertyChanged
{
    private int _Number;
    public int Number
    {
        get { return _Number; }
        set
        {
            _Number = value;
            NotifyPropertyChanged();
            NotifyPropertyChanged("Calculated");
        }
    }

    public int Calculated { get { return 2 * Number; } }


    // INotifyPropertyChanged implementation
    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged([CallerMemberName] string prop = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(prop));
    }
}

MainWindow构造函数:

MainWindow constructor:

public MainWindow()
{
    InitializeComponent();

    var data = new List<ExampleItemViewModel>();
    data.Add(new ExampleItemViewModel { Number = 1 });
    data.Add(new ExampleItemViewModel { Number = 2 });

    grid1.DataContext = data;
}

会发生什么:DataGrid为 Number 和一个只读列,表示 Calculated 。由于列是自动生成的,因此将采用默认行为:更改数字时,源不会立即更新,因为该行处于编辑模式。编辑完成后将对其进行更新(例如,按Enter键或该行失去焦点)。更新源后,从属的已计算列值将更改为 Number 值的2倍。

What should happen: the DataGrid autogenerates an editable column for Number and a read-only column for Calculated. Since the columns are autogenerated, the default behavior applies: when you change a number, the source will not be updated immediately, because the row is in edit mode. It will be updated after the edit completes (eg. you press enter or the row loses focus). As soon as the source is updated, the dependent Calculated column value changes to 2 times the Number value.

这篇关于其他一些更改时,DataGrid中的从属列也不会更改(WPF C#)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆