zoukankan      html  css  js  c++  java
  • 无废话WPF系列14:命令

    一、WPF为何需要命令

    我们已经知道WPF里已经有了路由事件,可以发布及传播一些消息,那为什么还需要命令呢?这是因为事件指负责发送消息,对消息如何处理则不管,而命令是有约束力,每个接收者对命令执行统一的行为,比如菜单上的保存,工具栏上的保存都必须是执行同样的保存。

    二、命令系统的基本元素

    命令(Command):实现了ICommand接口的类,经常使用的有RoutedCommand类

    命令源: 是命令的发送者,是实现了ICommandSource接口的类,大部分界面的控件都实现了这个接口,Button, MenuItem 等等。

    命令目标:命令的接收者,命令目标是视线了IInputElement接口的类。

    命令关联:负责一些逻辑与命令关联起来,比如判断命令是否可以执行,以及执行完毕后做一些处理。

    三、四个命令元素之间的关系

    image

    四、命令示例

    我们让一个按钮发送Hello命令给文本框,文本框接收这个命令后显示“Nice to meet you”.

    <Window x:Class="DeepXAML.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:DeepXAML"       
            xmlns:sys="clr-namespace:System;assembly=mscorlib"
            Title="MainWindow" Height="250" Width="450">
       
        <StackPanel x:Name="stackPanel">
            <TextBox x:Name="textBox1" Margin="10"></TextBox>
            <TextBox x:Name="textBox2" Margin="10"></TextBox>
            <Button x:Name="btnHello" Margin="10">Hello</Button>
        </StackPanel>
    </Window>

    后台代码

    using System;
    using System.Collections.Generic;
    using System.Windows;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Controls;
    using System.Windows.Input;
    
    namespace DeepXAML
    {
        public partial class MainWindow : Window
        {
            private RoutedCommand helloCmd = new RoutedCommand("Hello", typeof(MainWindow));
    
            public MainWindow()
            {
                InitializeComponent();
    
                this.btnHello.Command = this.helloCmd;
                this.helloCmd.InputGestures.Add(new KeyGesture(Key.H, ModifierKeys.Alt));
                this.btnHello.CommandTarget = this.textBox1;
                this.btnHello.CommandTarget = this.textBox2;
    
                CommandBinding cb = new CommandBinding();
                cb.Command = this.helloCmd;
                cb.CanExecute += new CanExecuteRoutedEventHandler(cb_CanExecute);
                cb.Executed += new ExecutedRoutedEventHandler(cb_Executed);
    
                this.stackPanel.CommandBindings.Add(cb);
            }
    
            void cb_Executed(object sender, ExecutedRoutedEventArgs e)
            {            
                this.textBox1.Text = "Nice to meet you";
                this.textBox2.Text = "Nice to meet you";
                e.Handled = true;
               
            }
    
            void cb_CanExecute(object sender, CanExecuteRoutedEventArgs e)
            {
                if (!string.IsNullOrEmpty(textBox1.Text) || !string.IsNullOrEmpty(textBox2.Text))
                {
                  e.CanExecute=false;
                }
                else
                {
                    e.CanExecute = true;
                }
    
                // 避免继续传递
                e.Handled = true;            
            }
        }
    }

    执行时

    一开始按钮状态可用,也就是命令可执行

    image

    点击按钮后:

    image

    清空一个TextBox,按钮仍然不可执行,因为没达到可执行的条件,两个都清空时,按钮重回可执行状态

    五、WPF的命令库

    WPF提供常用应用程序所用的命令集,常用的命令集包括:ApplicationCommands, ComponentCommands, NavigationCommands, MediaCommands和EditingCommands。
    ApplicationCommands(应用程序命令):
    CancelPrint:取消打印
    Close:关闭
    ContextMenu:上下文菜单
    Copy:复制
    CorrectionList: Gets the value that represents the Correction List command.
    Cut:剪切
    Delete:删除
    Find:查找
    Help:帮助
    New:新建
    NotACommand:不是命令,被忽略
    Open:打开
    Paste:粘贴
    Print:打印
    PrintPreview:打印预览
    Properties:属性
    Redo:重做
    Replace:取代
    Save:保存
    SaveAs:另存为
    SelectAll:选择所有的
    Stop:停止
    Undo:撤消
    ComponentCommands(组件命令):
    ExtendSelection:后接Down/Left/Right/Up, 比如:ExtendSelectionDown(Shift+Down,Extend Selection Down),ExtendSelectionLeft等
    Move:后接Down/Left/Right/Up, 如:MoveDown
    MoveFocus:后接Down/Forward/Back/Up, 如:MoveFocusDown
    MoveFocusPage:后接Down/Up,如:MoveFocusPageUp
    MoveTo:后接End/Home/PageDown/PageUp,比如:MoveToPageDown
    ScrollByLine
    ScrollPage:后接Down/Left/Right/Up,比如:ScrollPageLeft
    SelectTo:End/Home/PageDown/PageUp,比如:SelectToEnd
    NavigationCommands(导航命令):
    Browse浏览: 后接Back/Forward/Home/Stop, 比如:BrowseBack
    缩放显示:DecreaseZoom, IncreaseZoom, Zoom
    Favorites(收藏)
    页面:FirstPage, LastPage, PreviousPage, NextPage,GoToPage
    NavigateJournal
    Refresh(刷新)
    Search(搜索)
    MediaCommands(多媒体控制命令):
    Treble高音:DecreaseTreble,IncreaseTreble
    Bass低音:BoostBass,DecreaseBass,IncreaseBass
    Channel频道:ChannelDown,ChannelUp
    MicrophoneVolume麦克风音量调节:DecreaseMicrophoneVolume,IncreaseMicrophoneVolume,MuteMicrophoneVolume
    ToggleMicrophoneOnOff:麦克风开关
    Volume音量: DecreaseVolume,IncreaseVolume,MuteVolume
    Rewind, FastForward(回放,快进)
    Track轨道:PreviousTrack,NextTrack [上一段(节)]
    Play,Pause,Stop,Record(播放,暂停,停止,录制)
    TogglePlayPause
    Select选择
    EditingCommands(编辑/排版类命令):
    Align对齐:AlignCenter,AlignJustify,AlignLeft,AlignRight(居中,撑满,左对齐,右对齐)
    Backspace退格
    TabForward,TabBackward(Tab前缩,Tab向后)
    FontSize字体大小:DecreaseFontSize,IncreaseFontSize
    Indentation缩排:DecreaseIndentation, IncreaseIndentation
    Delete删除: Delete选中部分,DeleteNextWord:删除后一字,DeletePreviousWord:删除前一字
    EnterLineBreak:换行
    EnterParagraphBreak:换段
    CorrectSpellingError/IgnoreSpellingError:纠正/忽略拼写错误
    MoveUpByLine,MoveDownByLine: 上/下移一行,
    MoveUpByPage,MoveDownByPage: 上/下移一页
    MoveUpByParagraph,MoveDownByParagraph: 上/下移一段
    MoveLeftByCharacter/MoveRightByCharacter:左/右移一字符
    MoveLeftByWord/MoveRightByWord 左/右移一词
    MoveToDocumentStart/MoveToDocumentEnd:到文章开头/结尾
    MoveToLineStart/MoveToLineEnd:到一行的开头/结尾
    SelectUpByLine,SelectDownByLine:向上/下选一行
    SelectUpByPage,SelectDownByPage:向上/下选一页
    SelectUpByParagraph,SelectDownByParagraph:向上/下选一段
    SelectLeftByCharacter,SelectRightByCharacter:向左/右选中一字
    SelectLeftByWord,SelectRightByWord:向左/右选中一词
    SelectToDocumentStart,SelectToDocumentEnd: 选中到篇头/篇尾
    SelectToLineStart/SelectToLineEnd:选中到行首/行尾
    ToggleBold, ToggleItalic, ToggleUnderline(加粗,斜体,下划线)
    ToggleBullets, ToggleNumbering(列表:加点,加数字)
    ToggleInsert:插入
    ToggleSuperscript,ToggleSubscript(上标字,下标字)

    六、命令参数

    命令大部分都是类的静态属性,也就是示例只有一个,那么如果两个按钮使用同一个命令如何区分呢?比如新建一个Project,如何区分新建的是Library还是WPF呢?我们可以使用CommandParameter

    XAML:

    <Window x:Class="DeepXAML.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:DeepXAML"       
            xmlns:sys="clr-namespace:System;assembly=mscorlib"
            Title="MainWindow" Height="250" Width="450">
        <Window.CommandBindings>
            <CommandBinding Command="New" CanExecute="New_CanExecute" Executed="New_Executed"></CommandBinding>
        </Window.CommandBindings>
            <StackPanel x:Name="stackPanel">        
            <TextBox x:Name="textBox" Margin="10"></TextBox>
            <Button x:Name="btnWPF" Margin="10" Command="New" CommandParameter="WPF">新建WPF</Button>
            <Button x:Name="btnLibrary" Margin="10" Command="New" CommandParameter="Library">新建Library</Button>
        </StackPanel>
    </Window>

    后台代码:

    using System;
    using System.Collections.Generic;
    using System.Windows;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Controls;
    using System.Windows.Input;
    
    namespace DeepXAML
    {
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void New_CanExecute(object sender, CanExecuteRoutedEventArgs e)
            {
                e.CanExecute = string.IsNullOrEmpty(textBox.Text);
            }
    
            private void New_Executed(object sender, ExecutedRoutedEventArgs e)
            {
                if (e.Parameter.ToString() == "Library")
                {
                    this.textBox.Text+= "建一个Library";
                }
                if (e.Parameter.ToString() == "WPF")
                {
                    this.textBox.Text += "建一个WPF";
                }            
            }
        }           
    }

    运行:

    image

    点击第一个按钮

    image

    清空文本框再点击第二个按钮

    image

    扫码关注公众号,了解更多管理,见识,育儿等内容

    作者: 王德水
    出处:http://www.cnblogs.com/cnblogsfans
    版权:本文版权归作者所有,转载需经作者同意。

  • 相关阅读:
    mybatis批量更新报错
    Axure8破解码
    小程序开发-Step1
    2018新年计划
    java 写 Excel(不生成实体文件,写为流的形式)
    git 生成公钥 使用命令行无需输入用户名密码(windows)
    Node.js:上传文件,服务端如何获取文件上传进度
    Express:模板引擎深入研究
    windows下nginx的安装及使用
    Chrome开发者工具详解-Network面板
  • 原文地址:https://www.cnblogs.com/cnblogsfans/p/1966167.html
Copyright © 2011-2022 走看看