1

我正在开发 WPF LOB 应用程序并使用 Prism 和委托命令将 UI 与视图模型分开。

当用户从 UI(而不是视图模型或服务)对特定单元格进行更改时,我需要调用其他一些功能。

我已经创建了附加行为

public static class DataGridCellEditEndingBehaviour
{
    private static readonly DependencyProperty CellEditEndingProperty
        = DependencyProperty.RegisterAttached(
        "CellEditEnding",
        typeof(CellEditEnding),
        typeof(DataGridCellEditEndingBehaviour),
        null);

    public static readonly DependencyProperty CommandProperty
        = DependencyProperty.RegisterAttached(
        "Command",
        typeof(ICommand),
        typeof(DataGridCellEditEndingBehaviour),
        new PropertyMetadata(OnSetCommandCallback));

    public static readonly DependencyProperty CommandParameterProperty
        = DependencyProperty.RegisterAttached(
       "CommandParameter",
       typeof(object),
       typeof(DataGridCellEditEndingBehaviour),
       new PropertyMetadata(OnSetCommandParameterCallback));

    public static ICommand GetCommand(DataGrid control)
    {
        return control.GetValue(CommandProperty) as ICommand;
    }

    public static void SetCommand(DataGrid control, ICommand command)
    {
        control.SetValue(CommandProperty, command);
    }

    public static void SetCommandParameter(DataGrid control, object parameter)
    {
        control.SetValue(CommandParameterProperty, parameter);
    }

    public static object GetCommandParameter(DataGrid control)
    {
        return control.GetValue(CommandParameterProperty);
    }

    private static void OnSetCommandCallback
        (DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
    {
        DataGrid control = dependencyObject as DataGrid;
        if (control != null)
        {
            CellEditEnding behavior = GetOrCreateBehavior(control);
            behavior.Command = e.NewValue as ICommand;
        }
    }

    private static void OnSetCommandParameterCallback
        (DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
    {
        DataGrid control = dependencyObject as DataGrid;
        if (control != null)
        {
            CellEditEnding behavior = GetOrCreateBehavior(control);
            behavior.CommandParameter = e.NewValue;
        }
    }

    private static CellEditEnding GetOrCreateBehavior(DataGrid control)
    {
        CellEditEnding behavior =
            control.GetValue(CellEditEndingProperty) as CellEditEnding;
        if (behavior == null)
        {
            behavior = new CellEditEnding(control);
            control.SetValue(CellEditEndingProperty, behavior);
        }
        return behavior;
    }
}

public class CellEditEnding : CommandBehaviorBase<DataGrid>
{
    public CellEditEnding(DataGrid control)
        : base(control)
    {
        control.CellEditEnding += OnCellEditEnding;
    }

    private void OnCellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
    {
        ExecuteCommand();
    }
}

我可以使用同样的方法调用

local:DataGridCellEditEndingBehaviour.Command ="{Binding CellChangedCommand}"
  1. 当事件被调用时,我在VM的delegateCommand中没有得到任何事件参数,我如何检索事件参数,我可以通过命令参数设置它吗?如果是这样,我如何将事件参数传递给委托命令?

  2. 在 CellEditEndigEvent 期间,该值尚未存储到 VM 中,因为它仍在转换中,有没有办法可以强制它从处理程序发生,所以我不需要从 CellEditEndingEventArgs 读取值,而是可以直接从VM读取?

4

2 回答 2

0

是附属物。你使用它就像 local:DataGridCellEditEndingBehaviour.CommandParameter="{Binding against any you want to pass}"

您可能已经实现了自定义 DataGrid,它具有指示已编辑单元格的自定义属性或类似的内容。

于 2012-09-28T19:44:00.090 回答
0

我在尝试解决类似问题时遇到了这个问题 - 在 MVVM 应用程序中,我们有一个带有 DataGrid 的 UserControl,因此我们需要将 RowEditEnding 事件绑定到命令。我无法完全按照上面的示例进行操作,也无法确定如何找到 CommandBehaviorBase。

部分基于MvvmLight EventToCommand 和 WPFToolkit DataGrid 双击的答案,我实现了我们的 AttachedBehaviour 如下:

Public Class DataGridHelper
Public Shared ReadOnly RowEditEndingCommandProperty As DependencyProperty =
    DependencyProperty.RegisterAttached("RowEditEndingCommand",
                                        GetType(ICommand),
                                        GetType(DataGridHelper),
                                        New UIPropertyMetadata(AddressOf OnRowEditEnding))

Public Shared Sub SetRowEditEndingCommand(control As DataGrid, command As ICommand)
    control.SetValue(RowEditEndingCommandProperty, command)
End Sub

Private Shared Sub OnRowEditEnding(dependencyObject As DependencyObject, e As DependencyPropertyChangedEventArgs)
    Dim control As DataGrid = TryCast(dependencyObject, DataGrid)
    If control Is Nothing Then
        Throw New InvalidOperationException("This behavior can be attached to a DataGrid item only.")
    End If

    If e.NewValue IsNot Nothing AndAlso e.OldValue Is Nothing Then
        AddHandler control.RowEditEnding, AddressOf RowEditEnding
    ElseIf e.NewValue Is Nothing AndAlso e.OldValue IsNot Nothing Then
        RemoveHandler control.RowEditEnding, AddressOf RowEditEnding
    End If
End Sub

Private Shared Sub RowEditEnding(sender As Object, e As DataGridRowEditEndingEventArgs)
    Dim element As UIElement = DirectCast(sender, UIElement)
    Dim command As ICommand = DirectCast(element.GetValue(DataGridHelper.RowEditEndingCommandProperty), ICommand)
    'command.Execute(Nothing)
    command.Execute(e)
End Sub
End Class

到目前为止,这似乎有效,并且看起来比上面的方法更简单。我们将 DataGridRowEditEndingEventArgs 传递回参数中的 Command,因此它在 ViewModel 中可用。这可能也适用于 CellEditEnding 事件。

于 2012-11-15T03:55:41.240 回答