DataGrid单元格更改后,ObservableCollection不会更新

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DataGrid单元格更改后,ObservableCollection不会更新相关的知识,希望对你有一定的参考价值。

我是wpfmvvm 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不会更新的主要内容,如果未能解决你的问题,请参考以下文章

根据值更改 DataGrid 单元格颜色

如何使用 WPF Toolkit Datagrid 更改单元格的背景颜色

WPF使用转换器更改datagrid单元格背景颜色

在Timer Tick C#表单上更改DataGrid单元格的背景颜色

EasyUI datagrid editCell 编辑完单元格后如何取消编辑状态?

easyui前台改变datagrid某单元格的值