WPF MVVM基于焦点项执行不同的操作

时间:2015-03-29 15:58:12

标签: c# wpf mvvm datagrid focus

我正在MVVM Patern中开发一个WPF应用程序。该应用程序有一个命令栏和按钮,用于保存和删除记录。

enter image description here

该应用程序还有一个主详细信息表单。它是一个用户控件和一个DataGrid。

  • 主块:客户订单

  • 详细信息块:客户订单行

    (一对多关系)。

问题:

单击命令栏中的按钮时,需要执行不同的操作,具体取决于所关注的项目。

例如,如果我单击“删除”按钮

  1. 当DataGrid具有时,它应仅删除DataGrid行中的记录 焦点和行选择。 例如。应该调用DeleteRows()方法。

  2. 如果主块具有焦点而不是数据网格聚焦,则应删除整个记录。 例如。应该调用DeleteRecord()方法。

  3. 据我所知,我可以使用键盘焦点和逻辑焦点管理器实现此目的。 但我无法找到合适的解决方案。我应该考虑一下,当点击删除按钮时,我应该忽略删除按钮的焦点。

    请使用示例代码帮助我解决此问题。

1 个答案:

答案 0 :(得分:0)

由于您正在使用MVVM模式,我假设命令栏中的按钮在视图模型中具有相应的ICommand

您可以将DataGrid的{​​{1}}属性绑定到视图模型属性(当然,使用双向绑定),然后根据此属性值进行决策。如果是SelectedItem,那么null中当前没有选择任何项目,您可以删除整个记录。如果将其设置为实例,则会在DataGrid中选择一行,并且只能删除一行。

如果您需要确切知道哪个是最后关注的元素,您可以在后面的代码中使用Keyboard.PreviewLostKeyboardFocus附加事件。或者更好的是,使用依赖项属性创建自己的DataGrid,以便绑定到视图模型。

Behavior

然后,您可以将此行为应用于主块容器:

enum LastFocusedEntityType { None, Record, Row }

class LastFocusedEntityTrackingBehavior : Behavior<UIElement>
{
    public static readonly LastFocusedEntityProperty = DependencyProperty.Register(
        "LastFocusedEntity", 
        typeof(LastFocusedEntityType), 
        typeof(LastFocusedEntityTrackingBehavior),
        LastFocusedEntityType.None);

    public LastFocusedEntityType LastFocusedEntity
    {
        get { return (LastFocusedEntityType)this.GetValue(LastFocusedEntityProperty); }
        set { this.Setvalue(LastFocusedEntityProperty, value); }
    }

    protected override void OnAttached()
    {
        Keyboard.AddPreviewLostKeyboardFocusHandler(this.AssociatedObject, this.PreviewLostKeyboardFocusHandler);
    }

    private void PreviewLostKeyboardFocusHandler(object sender, KeyboardFocusChangedEventArgs e)
    {
        if (e.OldFocus is DataGrid)
        {
            this.LastFocusedEntity = LastFocusedEntityType.Row;
        }
        else
        {
            this.LastFocusedEntity = LastFocusedEntityType.Record;
        }
    }
}

在您的视图模型中,您的<UserControl> <i:Interaction.Behaviors> <local:LastFocusedEntityTrackingBehavior LastFocusedEntity="{Binding LastFocusedEntity, Mode=OneWayToSource}"/> </i:Interaction.Behaviors> </UserControl> ICommand方法应该查看Execute()属性值并决定下一步该做什么。

注意:我没有检查此代码是否编译。