我有一个带有某种复杂行为的ChildViewModels的ObservableCollection。
当我去编辑一行时--DataGrid进入'编辑模式' - 这有效地禁用了当前单元格之外的UI通知,直到提交了行 - 这是预期的行为,更重要的是它可以被更改吗? / p>
示例:
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;
}
}
答案 0 :(得分:7)
使用BindingGroup
在DataGrid中实现此行为。 DataGrid设置ItemsControl.ItemBindingGroup
以便将BindingGroup
应用于每一行。它会在MeasureOverride
中初始化,因此您可以覆盖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;
}
}
}
答案 1 :(得分:4)
这是一个非常古老的问题,但是一个更好的解决方案并不需要子类化DataGrid。只需在CellEditEnding事件中调用CommitEdit():
bool manualCommit = false;
private void MyDataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
if (!manualCommit)
{
manualCommit = true;
MyDataGrid.CommitEdit(DataGridEditingUnit.Row, true);
manualCommit = false;
}
}
答案 2 :(得分:0)
我遇到了这个问题,不得不手动将我的列添加到datagrid,然后在Column对象上设置Binding项。所以它会绑定到我的内容。
此外,我使ICollectionView
中的对象派生自IEditableObject
,因此当它们“更新”时,网格将自行刷新。
这很糟糕,但它是我必须做的才能让它发挥作用。
可选地,您可以创建自己的ObservableCollection,在添加和删除项目时附加/分离属性更改的处理程序。