代码之家  ›  专栏  ›  技术社区  ›  Goblin

DataGrid-更改编辑行为

  •  1
  • Goblin  · 技术社区  · 15 年前

    我有一个可以观察到的ChildViewModels集合,它们的行为有些复杂。

    当我去编辑一行时-数据网格进入“编辑模式”-这有效地禁用了当前单元格外的UI通知,直到提交该行-这是预期的行为,更重要的是它可以被更改吗?

    例子:

    public class ViewModel
    {
        public ViewModel()
        {
            Childs = new ObservableCollection<ChildViewModel> {new ChildViewModel()};
        }
        public ObservableCollection<ChildViewModel> Childs { get; private set; }
    }
    public class ChildViewModel : INotifyPropertyChanged
    {
        private string _firstProperty;
        public string FirstProperty
        {
            get { return _firstProperty; }
            set
            {
                _firstProperty = value;
                _secondProperty = value;
                OnPropetyChanged("FirstProperty");
                OnPropetyChanged("SecondProperty");
            }
        }
    
        private string _secondProperty;
        public string SecondProperty
        {
            get { return _secondProperty; }
            set
            {
                _secondProperty = value;
                OnPropetyChanged("SecondProperty");
            }
        }
    
        private void OnPropetyChanged(string property)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }
    

    在我们看来:

    <Window.Resources>
        <local:ViewModel x:Key="Data"/>
    </Window.Resources>
    <DataGrid DataContext="{Binding Source={StaticResource Data}}" ItemsSource="{Binding Childs}"/>
    

    请注意,编辑第一列时的第二个通知是如何隐藏的,直到您离开该行。

    编辑:实现IEditableObject不会执行任何操作:

    public class ChildViewModel : INotifyPropertyChanged,IEditableObject
    {
        ...
        private ChildViewModel _localCopy;
    
        public void BeginEdit()
        {
            _localCopy = new ChildViewModel {FirstProperty = FirstProperty, SecondProperty = SecondProperty};
        }
    
        public void EndEdit()
        {
            _localCopy = null;
        }
    
        public void CancelEdit()
        {
            SecondProperty = _localCopy.SecondProperty;
            FirstProperty = _localCopy.FirstProperty;
        }
    }
    
    3 回复  |  直到 8 年前
        1
  •  7
  •   Quartermeister    14 年前

    此行为在DataGrid中使用 BindingGroup . 数据网格集 ItemsControl.ItemBindingGroup 为了申请 每一排。它在 MeasureOverride ,以便可以重写 测量超越 把它们清理干净:

    public class NoBindingGroupGrid
        : DataGrid
    {
        protected override Size MeasureOverride(Size availableSize)
        {
            var desiredSize = base.MeasureOverride(availableSize);
            ClearBindingGroup();
            return desiredSize;
        }
    
        private void ClearBindingGroup()
        {
            // Clear ItemBindingGroup so it isn't applied to new rows
            ItemBindingGroup = null;
            // Clear BindingGroup on already created rows
            foreach (var item in Items)
            {
                var row = ItemContainerGenerator.ContainerFromItem(item) as FrameworkElement;
                row.BindingGroup = null;
            }
        }
    }
    
        2
  •  6
  •   user3690202    9 年前

    这是一个非常古老的问题,但是有一个更好的解决方案,它不需要对DataGrid进行子类化。只需在CellEditEnding事件中调用committedIt():

    bool manualCommit = false;
    
    private void MyDataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
    {
        if (!manualCommit)
        {
            manualCommit = true;
            MyDataGrid.CommitEdit(DataGridEditingUnit.Row, true);
            manualCommit = false;
        }
    }
    
        3
  •  0
  •   Muad'Dib    15 年前

    好吧,问题来了。Observable集合不会通知对象它包含的更改。它只在添加/删除等操作时发出通知。更新集合的操作是自操作。

    我遇到了这个问题,必须手动将列添加到datagrid,然后在Column对象上设置绑定项。好让它和我的内容结合起来。

    另外,我做的对象是在我的 ICollectionView IEditableObject 因此,当它们被“更新”时,网格将自我刷新。

    这很糟糕,但我要做的就是让它工作。

    或者,您可以创建自己的observeCollection,在添加和删除项时附加/分离属性更改的处理程序。