C# 当某些其他更改时,DataGrid中的依赖列不会更改(WPF C)
我在我的应用程序中有一堆订单,我想在datagrid中显示它们,并在原地编辑它们的属性。有一个名为Order的类,其权重属性取决于Item.weight和Order.Count。在ObservableCollection订单绑定到的datagrid中,我希望就地更改行。城市和项目值正在更改,但当项目或计数更改时,UI中的权重不会更新 -MyViewModelC# 当某些其他更改时,DataGrid中的依赖列不会更改(WPF C),c#,.net,wpf,data-binding,datagrid,C#,.net,Wpf,Data Binding,Datagrid,我在我的应用程序中有一堆订单,我想在datagrid中显示它们,并在原地编辑它们的属性。有一个名为Order的类,其权重属性取决于Item.weight和Order.Count。在ObservableCollection订单绑定到的datagrid中,我希望就地更改行。城市和项目值正在更改,但当项目或计数更改时,UI中的权重不会更新 -MyViewModel public class Order : INotifyPropertyChanged { private int _OrderI
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中编辑一行时,我想更新整个属性,但在这种情况下,我可以更改订单的项目、计数和城市,但权重不会更新。由于您想显示基于其他属性的计算权重值,您应该更改代码的以下部分: 将绑定设为单向,因为该值将始终在源中重新计算
<DataGridTextColumn Binding="{Binding Weight, Mode=OneWay}"
Header="وزن"
Width="100"
IsReadOnly="True"/>
通知计算的源属性中的相关更改。如果Item.Weight可能在Item实例中发生更改,则需要额外处理
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));
}
}
删除访问权重设置器的所有内容,例如在构造函数中
有关计算属性,请参见以下最小工作示例。在这种情况下,我依赖于自动生成的列,但是手写列也可以这样做
<Window
... your default generated window class, nothing special ... >
<Grid x:Name="grid1">
<DataGrid ItemsSource="{Binding}"/>
</Grid>
</Window>
主窗口构造函数:
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键或该行失去焦点。更新源后,相关计算列的值将更改为数值的2倍。欢迎使用SO!第一个问题做得好。你可以试着弄清楚你有什么问题。也许可以尝试重复您发布的代码数量,因为很难提取问题所在。另外,请详细说明根据您的情况,在代码中应在何处进行字段切换,并举例说明您希望获取的内容以及现在正在发生的事情。非常感谢。我对我的问题做了一些更改。如果我理解正确,显示的重量将是从Count*Item计算出来的值。重量,用户永远不会直接修改重量值?我现在假设一下,然后写一个答案……谢谢你的回答。我按照你说的步骤做了,但没有起作用。我想因为我是MVVM新手,所以我无法理解。我找到了一种解决方法,在项目或计数发生变化时分配权重:set{{u item=value;\u Weight=\u count*\u item.Weight;raiseProperteChanged;}set{\u Count=value;\u Weight=\u Count*\u Item.Weight;raisepropertechanged;}@Eti我添加了一个小示例,也许您会发现了解计算列很有用,并且它可能会帮助您理解为什么在您的案例中它不起作用。
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));
}
}
public MainWindow()
{
InitializeComponent();
var data = new List<ExampleItemViewModel>();
data.Add(new ExampleItemViewModel { Number = 1 });
data.Add(new ExampleItemViewModel { Number = 2 });
grid1.DataContext = data;
}