WPF体系结构混淆RE:路由命令,事件和手势 [英] WPF Architecture Confusion RE: Routed Commands, Events, and Gestures

查看:198
本文介绍了WPF体系结构混淆RE:路由命令,事件和手势的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在学习WPF时,我一直在阅读大量书籍和网站.似乎一直在回避我的一件事是,我们应该如何正确地连接RoutedCommands.在一篇文章中,作者指出,您的XAML文件的代码背后应该只包含对InitializeComponent的调用.我可以落后.它使XAML文件只不过是一个演示文稿文件,并且满足了我对分离关注点的不切实际的渴望.

In learning WPF, I've been reading scads of books and web sites. One thing that seems to keep evading me is how we are supposed to properly wire up RoutedCommands. In one article, the author pointed out that the codebehind for your XAML files is supposed to contain nothing more than the call to InitializeComponent. I can get behind that. It makes the XAML file nothing more than a presentation document, and satisifies my unholy craving for separation of concerns.

另一方面,我看到的每个解决双击事件的示例似乎都希望您编写代码.据我了解,我们希望摆脱代码隐藏文件中的重复代码(再次,我全力以赴),所以在我看来这不是正确的方法.菜单命令,工具栏按钮单击等也是如此.

On the other hand, every sample I've seen that addresses double-click events seems to want you to write code. It was my understanding that we wanted to get away from having repetitive code in the codebehind files (and, again, I'm all for that), so it seems to me that that's not the right way to do it. The same is true of menu commands, toolbar button clicks, and so forth.

例如,假设我有一个打开文档的命令.该命令必须显示打开"对话框,然后打开文档并将其缓存在应用程序状态. (此应用程序一次只允许您处理一个文档.)用户可以通过以下任一方式调用此命令:

Imagine, for instance, that I have a command to open a document. That command has to present the Open dialog, then open the document and cache it in the application state. (This application only allows you to work on one document at a time.) The user can invoke this command by either:

  • 选择文件->从菜单中打开.
  • 键入Ctrl + O.
  • 单击工具栏上的打开"按钮.

如果我信任Web上的大多数资源,则必须编写至少两个Click事件处理程序,然后调用该命令处理程序,从而污染代码隐藏文件.在我看来,这似乎挫败了拥有司令部的目的.我认为我在某处读到了一种方法,可以在XAML中以声明方式将命令绑定到这些东西,它将为您完成,甚至在命令无法执行时也将其禁用.但是现在我似乎找不到它了,也找不到如何做到这一点的好例子.

If I trust most of the sources on the Web, I have to write at least two Click event handlers that then invoke the command, polluting the codebehind file. That seems, to me, to defeat the purpose of having the Commands. I thought that I read somewhere that there was a way to bind the command to these things declaratively in XAML and it would do it for you, even disabling the command if it couldn't execute. But now I can't seem to find it, nor a decent example of how to do it.

有人可以向我解释一下吗?此时一切都开始像伏都教和弹片一样.

Could someone please explain this to me? It's all starting to look like voodoo and shrapnel at this point.

推荐答案

在WPF中进行命令非常繁琐,但确实可以解决为您更新IsEnabled的问题.这是规范的例子.步骤1是可选的,因为有很多内置的常用命令减少样板数量.

Commanding in WPF is quite cumbersome, but it does solve the problem of updating IsEnabled for you. Here's the canonical example. Step 1 is optional because there are a lot of built-in common commands to reduce the amount of boiler-plate.

步骤1.(可选)在静态类中创建命令

Step 1. (Optional) Create your command in a static class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;

namespace WpfApplication1
{
   public static class Commands
   {
      public static RoutedCommand WibbleCommand = new RoutedUICommand
      (
         "Wibble",
         "Wibble",
         typeof(Commands),
         new InputGestureCollection()
            {
               new KeyGesture(Key.O, ModifierKeys.Control)
            }
      );
   }
}

第2步:在xaml中声明命令绑定

Step 2: Declare command bindings in the xaml

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
   <Window.CommandBindings>
      <CommandBinding
         Command="{x:Static local:Commands.WibbleCommand}"
         Executed="WibbleCommandExecuted"
         CanExecute="WibbleCommandCanExecute"
      />
   </Window.CommandBindings>

第3步:连接控件(菜单,按钮等)

Step 3: Wire up your controls (menuitems, buttons etc)

此处的长绑定是为了纠正以下事实:默认情况下,Button将不使用命令文本.

The long binding here is to rectify the fact that Button by default won't use the command text.

  <Button Command="{x:Static local:Commands.WibbleCommand}" Width="200" Height="80">
     <TextBlock Text="{Binding Path=Command.Text, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}">
     </TextBlock>
  </Button>

第4步:在代码隐藏中实现Execute和CanExecute的处理程序

Step 4: Implement handlers for Execute and CanExecute in codebehind

小心CanExecute!这会经常被调用,所以在这里不要做任何昂贵的事情.

Careful with CanExecute! This will be called quite often, so try not to do anything expensive here.

  private void WibbleCommandExecuted(object sender, ExecutedRoutedEventArgs e)
  {
     MessageBox.Show("Wibbled!");
  }

  private void WibbleCommandCanExecute(object sender, CanExecuteRoutedEventArgs e)
  {
     e.CanExecute = DateTime.Now.Minute % 2 == 0;
  }

这篇关于WPF体系结构混淆RE:路由命令,事件和手势的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆