我有以下DataGrid
<DataGrid CanUserDeleteRows="True"
CanUserAddRows="True"
SelectedItem="{Binding SelectedResource, Mode=TwoWay}"
ItemsSource="{Binding Path=Resources, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged,
IsAsync=True}"> ... </<DataGrid>
我正在使用MVVM模式绑定到ObservableCollection<ResourceViewModel> Resources
,这很有用。我有一个添加新行的按钮,这是通过向ResourceViewModel
集合添加新Resources
来完成的 - 很棒。现在,我希望用户能够点击空的最后一行,这会自动在DataGrid
中创建一条新记录。
我确保DataGrid
有CanUserAddRows=True
。我确保我绑定的集合Resources
(ResourceViewModel
)中的类具有默认构造函数(无参数),并确保集合类型不是只读的。当用户单击最后一行时,默认构造函数将触发,但要正确实例化需要的新ResourceViewModel
对象,请引用Resources
集合的网格...
我想我可以在AttachedCommand
事件中使用CellBeginEdit
,然后在那里的可观察集合中添加一个新的ResourceViewModel
,是否有标准的方法来执行此操作?
请注意,我已阅读以下问题,这些对我没有帮助
编辑。事实证明,由于WPF DataGrid
中的错误,我在执行此操作时遇到了问题。见Nigel Spencer's Blog。但是,他的修复目前对我不起作用......
答案 0 :(得分:3)
据我了解,您知道如何正确地将新项目添加到数据绑定集合中,以便将新项目添加到DataGrid
,并且您的问题实际上与您如何在用户点击DataGrid
中的最后一行。在视图模型中处理某个事件的一般方法是创建一个Attached Property
(如果尚不存在),为您处理该事件。
例如,您可以创建一个Attached Property
,它将处理程序附加到相关事件,另一个类型ICommand
可以在调用事件处理程序时执行。然后,您可以在视图模型中编写ICommand
的功能(在其中向数据绑定集合中添加新项),数据将ICommand
实现绑定到Attached ICommand Property
。< / p>
由于我很确定你知道如何定义Attached Property
,我不会通过向你展示来侮辱你。如果我误解了你,或者没有让自己明白,请告诉我。
答案 1 :(得分:1)
这是一个附加属性,用于注册添加行的命令(假设源集合包含泛型类型参数):
public static readonly DependencyProperty RegisterAddCommandProperty = DependencyProperty.RegisterAttached("RegisterAddCommand", typeof(bool), typeof(DataGridExtensions), new PropertyMetadata(false, OnRegisterAddCommandChanged));
public static bool GetRegisterAddCommand(DependencyObject obj)
{
return (bool)obj.GetValue(RegisterAddCommandProperty);
}
public static void SetRegisterAddCommand(DependencyObject obj, bool value)
{
obj.SetValue(RegisterAddCommandProperty, value);
}
static void OnRegisterAddCommandChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (sender is DataGrid)
{
var DataGrid = sender as DataGrid;
if ((bool)e.NewValue)
DataGrid.CommandBindings.Add(new CommandBinding(AddCommand, AddCommand_Executed, AddCommand_CanExecute));
}
}
public static readonly RoutedUICommand AddCommand = new RoutedUICommand("AddCommand", "AddCommand", typeof(DataGridExtensions));
static void AddCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
var DataGrid = sender as DataGrid;
var ItemsSourceType = DataGrid.ItemsSource.GetType();
var ItemType = ItemsSourceType.GetGenericArguments().Single();
DataGrid.Items.Add(Activator.CreateInstance(ItemType));
}
static void AddCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = (sender as DataGrid).CanUserAddRows;
}
然后你可以将命令应用到这样的按钮:
<Button Command="{x:Static Extensions:DataGridExtensions.AddCommand}"/>
不要忘记指定命令目标。