【问题标题】:ObservableCollection is not update after DataGrid Cell ChangeDataGrid 单元格更改后 ObservableCollection 未更新
【发布时间】:2018-06-09 17:55:13
【问题描述】:

我是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 的itemsource 中添加了mode=twoway 对吗?但是当我调试时,员工类型列表集永远不会发生。为什么?如果我做的过程是错误的,请告诉我该怎么做?如果有不明白的请告诉我。谢谢。

【问题讨论】:

    标签: c# wpf mvvm data-binding


    【解决方案1】:

    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}"

    【讨论】:

    • 谢谢你,我认为 DataGridComboBoxColumn 对现在的设计很有用,我必须自定义组合(例如组合中的两列)。所以我使用了这个设计。
    【解决方案2】:

    此时您可能只是不了解完全绑定,没关系。

    Mode=TwoWay 表示当底层对象中的值发生更改以及用户更改 UI 上的值时,UI 上的绑定属性将发生更改。

    在您的情况下,您应该必须替换 UI 上的集合才能注意到更改。因此,到目前为止,您正在更改 ObservableCollection 的内容,因此您没有收到任何关于集合级别的通知。当您在 UI 上更改 EmpType 时,您应该会收到通知。

    清楚吗?

    【讨论】:

    • 请举例说明一下?谢谢
    • 我不确定这个案例是否真的存在任何例子。集合是一个复杂的对象,很难在 UI 上构建。我可能有点困惑,不明白你想要达到的目标。
    • @Lwin 仅当有人将新集合分配给属性时,才会调用集合属性的设置器。 UI 永远不会,永远不会那样做。想一想发生了什么:当您更改集合in 对象的属性值时,该操作不会创建新集合。为什么会呢?怎么可能?你为什么要它?当您设置类 C 的实例 B 的属性 A 时,您在该类的该实例上调用该属性的设置器,而不是在某个随机其他类上调用其他随机属性的设置器。
    • @cloudikka ,是的,目前我正在尝试学习 mvvm 结构并且没有代码隐藏。我是窗口窗体开发人员,我只是想升级我的知识。但是如你所知,窗口窗体和 wpf mvvm数据绑定结构完全不同。现在我只想知道datagrid和mvvm的更新过程。如何触发datagrid中的值变化?我需要像window form一样在datagrid中添加单元格值变化事件吗?
    猜你喜欢
    • 1970-01-01
    • 2014-11-05
    • 2019-10-25
    • 2015-08-24
    • 1970-01-01
    • 1970-01-01
    • 2011-06-29
    • 2014-12-13
    相关资源
    最近更新 更多