问题描述
当我去编辑一行时,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 - 更改编辑行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!