DataGrid单元格更改后,ObservableCollection不会更新
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DataGrid单元格更改后,ObservableCollection不会更新相关的知识,希望对你有一定的参考价值。
我是wpf
和mvvm databinding
的新人。现在我正在尝试使用数据网格进行crud处理。我有一个更新进程的问题。我希望在mvvm进程更新数据网格单元后得到更新值。
模型
public class EmployeeType : INotifyPropertyChanged
{
string _EmpType;
public string EmpType
{
get
{
return _EmpType;
}
set
{
if(_EmpType !=value)
{
_EmpType = value;
RaisePropertyChange("EmpType");
}
}
}
string _EmpTypeDesc;
public string EmpTypeDesc
{
get
{
return _EmpTypeDesc;
}
set
{
if(_EmpTypeDesc!=value)
{
_EmpTypeDesc = value;
RaisePropertyChange("EmpTypeDesc");
}
}
}
bool _OTRounding;
public bool OTRounding
{
get
{
return _OTRounding;
}
set
{
if(_OTRounding!=value)
{
_OTRounding = value;
RaisePropertyChange("OTRounding");
}
}
}
decimal _EarlyOTTimeBuffer;
public decimal EarlyOTTimeBuffer
{
get
{
return _EarlyOTTimeBuffer;
}
set
{
if(_EarlyOTTimeBuffer!=value)
{
_EarlyOTTimeBuffer = value;
RaisePropertyChange("EarlyOTTimeBuffer");
}
}
}
string _EarlyOTRounding;
public string EarlyOTRounding
{
get
{
return _EarlyOTRounding;
}
set
{
if(_EarlyOTRounding!=value)
{
_EarlyOTRounding = value;
RaisePropertyChange("EarlyOTRounding");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
void RaisePropertyChange(string prop)
{
if(PropertyChanged !=null)
{
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}
查看模型
class EmployeeTypeViewModel:ViewModelBase
{
private ObservableCollection<EmployeeType> _EmployeeTypeList = new ObservableCollection<EmployeeType>();
private ObservableCollection<TimeFormat> _ThreeTimeFormat = new ObservableCollection<TimeFormat>();
public ObservableCollection<TimeFormat> ThreeTimeFormat
{
get
{
return _ThreeTimeFormat;
}
set
{
_ThreeTimeFormat = value;
RaisePropertyChanged("ThreeTimeFormat");
}
}
public ObservableCollection<EmployeeType> EmployeeTypeList
{
get
{
return _EmployeeTypeList;
}
set
{
_EmployeeTypeList = value;
RaisePropertyChanged("EmployeeTypeList");
}
}
public EmployeeType _SelectedEarlyOTRounding;
public EmployeeType SelectedEarlyOTRounding
{
get
{
return _SelectedEarlyOTRounding;
}
set
{
if (_SelectedEarlyOTRounding != value)
{
_SelectedEarlyOTRounding = value;
RaisePropertyChanged("SelectedEarlyOTRounding");
}
}
}
public EmployeeTypeViewModel()
{
_EmployeeTypeList = DataAccess.EmployeeTypeDataAccessor.GetAllEmployeeTypes();
ThreeTimeFormat = TMSHelper.GetThreeTimeFormat();
}
}
视图
<UserControl.Resources>
<ViewModels:EmployeeTypeViewModel x:Key="ViewModel"/>
</UserControl.Resources>
<Grid DataContext="{Binding Source={StaticResource ViewModel}}">
<DataGrid Margin="10,10,9.6,10.2" x:Name="empgrid" ItemsSource="{Binding EmployeeTypeList,Mode=TwoWay}" AutoGenerateColumns="False" >
<DataGrid.Columns>
<DataGridTextColumn Header="EmpType" Binding="{Binding EmpType,Mode=TwoWay}"/>
<DataGridCheckBoxColumn Header="OTRounding" Binding="{Binding OTRounding}"/>
<DataGridTextColumn Header="Description" Binding="{Binding EmpTypeDesc}"/>
<DataGridTextColumn Header="Early OT Time Buffer" Binding="{Binding EarlyOTTimeBuffer}"/>
<DataGridTemplateColumn Header="Early OT Time Rounding">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox SelectedValuePath="Value" DisplayMemberPath="Key" ItemsSource="{Binding Path=DataContext.ThreeTimeFormat,ElementName=empgrid}" SelectedValue="{Binding EarlyOTRounding,Mode=TwoWay}" SelectedItem="{Binding SelectedEarlyOTRounding}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
我刚才意识到事情就是如果我在datagrid单元格中更改了值,它将自动更新viewmodel中的EmployeeTypeList
。因为我在grid.right的mode=twoway
中添加了itemsource
?但是当我调试时,套件EmployeeTypeList永远不会发生。为什么?如果我的做法有误,请让我知道怎么做?如果您不明白,请告诉我。谢谢。
你可能只是不明白在这一点上完全绑定并且没关系。
Mode=TwoWay
表示当底层对象中的值更改时以及用户更改UI上的值时,将在UI上更改绑定属性。
在您的情况下,您应该在UI上替换集合以注意更改。所以,你正在改变ObservableCollection
的内容,因此你没有收到关于收集级别的任何通知。当您在UI上更改EmpType
时,您应该已获得通知。
清楚吗?
BindingMode值之一。默认值为Default,它返回目标依赖项属性的默认绑定模式值。但是,默认值因每个依赖项属性而异。通常,用户可编辑的控件属性(例如文本框和复选框的属性)默认为双向绑定,而大多数其他属性默认为单向绑定。
(来源:MSDN)
所以一般可以编辑的地方通常不需要通知
现在,为了让你的组合框正常工作试试这个。
我通常使用它并且完美地工作
<DataGridComboBoxColumn Header="Early OT Time Rounding"
DisplayMemberPath="Key"
SelectedValuePath="Value"
SelectedValueBinding="{Binding EarlyOTRounding, UpdateSourceTrigger=PropertyChanged}"
>
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext.ThreeTimeFormat, UpdateSourceTrigger=PropertyChanged}"/>
<Setter Property="Width" Value="280" />
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext.ThreeTimeFormat, UpdateSourceTrigger=PropertyChanged}"/>
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
注意这个DataGridComboBoxColumn
必须将SelectedValueBinding
属性设置为EmployeeTypeList
中的项目,以便在列表中更改所选值
在你的情况下:
SelectedValueBinding="{Binding EarlyOTRounding, UpdateSourceTrigger=PropertyChanged}"
以上是关于DataGrid单元格更改后,ObservableCollection不会更新的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 WPF Toolkit Datagrid 更改单元格的背景颜色
在Timer Tick C#表单上更改DataGrid单元格的背景颜色