本文介绍了DataGrid - 更改编辑行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



当我去编辑一行时,DataGrid进入编辑模式 - 这样会有效地禁用目前的单元格之外的UI通知,直到该行被提交 - 是这个预期的行为,更重要的是可以更改吗?



示例:

  public class ViewModel 
{
public ViewModel()
{
Childs = new ObservableCollection< ChildViewModel> {new ChildViewModel()};
}
public ObservableCollection< ChildViewModel>孩子{get;私人集合
}
public class ChildViewModel:INotifyPropertyChanged
{
private string _firstProperty;
public string FirstProperty
{
get {return _firstProperty; }
set
{
_firstProperty = value;
_secondProperty = value;
OnPropetyChanged(FirstProperty);
OnPropetyChanged(SecondProperty);
}
}

私有字符串_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;
}
}


解决方案

行为在DataGrid中使用。 DataGrid设置,以便将 BindingGroup 应用于每一行。它在 MeasureOverride 中初始化,因此您可以覆盖 MeasureOverride 并将其清除:

  public class NoBindingGroupGrid 
:DataGrid
{
protected override Size MeasureOverride(Size availableSize)
{
var desiredSize = base.MeasureOverride(availableSize);
ClearBindingGroup();
return desiredSize;
}

private void ClearBindingGroup()
{
//清除ItemBindingGroup,因此不适用于新行
ItemBindingGroup = null;
//在已创建的行上清除BindingGroup
foreach(项目中的var项目)
{
var row = ItemContainerGenerator.ContainerFromItem(item)as FrameworkElement;
row.BindingGroup = null;
}
}
}


I have an ObservableCollection of ChildViewModels with somewhat complex behaviour.

When I go to edit a row - the DataGrid goes into 'edit-mode' - this effectively disables UI-notifications outside the current cell until the row is committed - is this intended behaviour and more importantly can it be changed?

Example:

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

And in View:

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

Notice how the second notification when editing first column is hidden until you leave the row.

EDIT: Implementing IEditableObject does nothing:

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;
    }
}
解决方案

This behavior is implemented in DataGrid using BindingGroup. The DataGrid sets ItemsControl.ItemBindingGroup in order to apply a BindingGroup to every row. It initializes this in MeasureOverride, so you can override MeasureOverride and clear them out:

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

这篇关于DataGrid - 更改编辑行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 22:39