1

私は WPF LOB アプリケーションに取り組んでおり、Prism とデリゲート コマンドを使用して UI をビュー モデルから分離しています。

ユーザーが (ビュー モデルやサービスからではなく) UI から特定のセルを変更するたびに、他の機能を呼び出す必要があります。

Attached Behavior を作成しました

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 で eventargs を取得できません。イベント引数を取得するにはどうすればよいですか? コマンド パラメータで設定できますか? もしそうなら、どうすればイベント引数をデリゲートコマンドに渡すことができますか?

  2. CellEditEndigEvent の間、VM はまだ遷移中であるため、値はまだ VM に格納されていません。ハンドラーから値を強制的に発生させる方法はありますか?そのため、CellEditEndingEventArgs から値を読み取る必要はありません。代わりに、 VMから直接読み取る?

4

2 に答える 2

0

添付プロパティです。local:DataGridCellEditEndingBehaviour.CommandParameter="{Binding against what you want to pass}" のように使用します

編集されたセルまたは線に沿った何かを示すカスタム プロパティを持つカスタム DataGrid を実装している可能性があります。

于 2012-09-28T19:44:00.090 に答える
0

同様の問題を解決しようとしてこれに遭遇しました-MVVMアプリでは、DataGridを備えたUserControlがあるため、RowEditEndingイベントをコマンドにバインドする必要があります。上記の例を完全に追うことができず、CommandBehaviorBase を見つける方法を特定できませんでした。

MvvmLight EventToCommand および WPFToolkit DataGrid double-clickでの回答に部分的に基づいて、次のように 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 に答える