当前位置:网站首页 / WPF / 正文

写给自己的WPF4.5 笔记14[简洁记忆命令Command]

时间:2015年02月04日 | 作者 : aaronyang | 分类 : WPF | 浏览: 4256次 | 评论 0

文章写给自己的,请勿转载和乱喷

  1.  命令库

ApplicationCommands:例如Cut、Copy、New、Open等

Image 11.png

NavigationCommand:BrowseBack、BrowseForward和NextPage、Fresh、IncreaseZoom等

EditingCommands:MoveToLineEnd、SelectToLineEnd等

ComponentCommands:用户界面组件使用的命令,移动和选择内容的命令,类似EditingCommands

MediaCommands:Play、Pause、NextTrack以及IncreaseVolume等

使用系统的可以简写,直接名字,或者命令库.名字

DEMO:

<Window x:Class="Commands.TestNewCommand"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="TestNewCommand" Height="134" Width="281"
    >
  <Window.CommandBindings>
    <CommandBinding Command="ApplicationCommands.New"
      Executed="NewCommand" />
  </Window.CommandBindings>

  <StackPanel >
    <Menu>
      <MenuItem Header="File">
        <MenuItem Command="New"></MenuItem>
      </MenuItem>
    </Menu>

    <Button Margin="5" Padding="5" Command="ApplicationCommands.New"
            ToolTip="{x:Static ApplicationCommands.New}">New</Button>
    <Button Margin="5" Padding="5" Visibility="Hidden" Command="ApplicationCommands.Open">Open (unwired)</Button>
      <Button Margin="5" Padding="5" Visibility="Hidden" Click="cmdDoCommand_Click" >DoCommand</Button>
    </StackPanel>
</Window>
   private void NewCommand(object sender, ExecutedRoutedEventArgs e)
        {            
            MessageBox.Show("New command triggered by " + e.Source.ToString());
        }

        private void cmdDoCommand_Click(object sender, RoutedEventArgs e)
        {
            this.CommandBindings[0].Command.Execute(null);
           // ApplicationCommands.New.Execute(null, (Button)sender);
        }

其他学习,TextBox的AcceptsReturn="True",表示回车可以换行

2. 命令模型:命令绑定对象,命令目标对象,命令源    ,接口:ICommand

Image 9.png

命令好处,一处多用,还可以绑定快捷键

3.RoutedCommand类是WPF唯一实现ICommand接口的,原有方法加了几个参数,例如IInputElement---相关拓展:CommandBinding

Image 10.png

执行顺序,先CanExecute返回true或者false,true就Execute,false就结束

引出 命令名称(Name), 包含命令的类(OwnerType)、任何可用于触发命令的按键或者鼠标操作(InputGestures)。

4.RoutedUICommand类(继承RoutedCommand),ICommandSource接口的三个属性:Command,CommandParameter,CommandTarget

自定义命令类:

   public class DataCommands
    {
        private static RoutedUICommand requery;
        static DataCommands()
        {
            InputGestureCollection inputs = new InputGestureCollection();
            inputs.Add(new KeyGesture(Key.R, ModifierKeys.Control, "Ctrl+R"));
            requery = new RoutedUICommand(
              "Requery", "Requery", typeof(DataCommands), inputs);
        }
         
        public static RoutedUICommand Requery
        {
            get { return requery; }
        }
    }
<Window x:Class="Commands.CustomCommand"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Commands" Height="300" Width="300"
    xmlns:local="clr-namespace:Commands"
    >
  <Window.CommandBindings>

    <CommandBinding Command="local:DataCommands.Requery"
                    Executed="RequeryCommand"/>
  </Window.CommandBindings>

  <Grid>
    <Button Margin="5" Command="local:DataCommands.Requery">Requery</Button>      
    </Grid>
</Window>
 private void RequeryCommand(object sender, ExecutedRoutedEventArgs e)
        {
            MessageBox.Show("Requery");
        }

创建静态的RoutedUICommand对象,前台绑定static的命令,窗体定义绑定基础等事件,下方引入空间后,指定Command命令

前台的CommandBindings     后台写法

ApplicationCommands.New.Text = "Completely New";
            CommandBinding bindingNew = new CommandBinding(ApplicationCommands.New);
            bindingNew.Executed += NewCommand;

            this.CommandBindings.Add(bindingNew);

默认命令,自定义命令,都有文本,默认快捷键字符串,正如上方自定义命令的代码

禁用命令的小demo,事件置空,CanExecute为false并阻止命令冒泡,或者其他

      txt.CommandBindings.Add(new CommandBinding(ApplicationCommands.Cut, null, SuppressCommand));
      txt.InputBindings.Add(new KeyBinding(ApplicationCommands.NotACommand, Key.C, ModifierKeys.Control));
   private void SuppressCommand(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = false;
            e.Handled = true;
        }

显示Command中的字

Image 12.png

或者

Image 13.png

或者,把提示放到ToolTip中,不放到Content

后台调用命令:命令.Execute(命令参数,目标元素)    或者    如果前台绑定了命令     this.CommandBinding[0].Command.Execute(命令参数)  关于

关于目标元素的指定理解

Image 14.png

设置目标组,所有的CommandTarget都指定了1个 :

Image 15.png

创建单个CommandBinding设置了key

Image 16.png


★大需求:下面的代码是简单命令队列,命令队列的需求

 public class CommandHistoryItem
    {
        public string CommandName
        {
            get;
            set;
        }

        public UIElement ElementActedOn
        {
            get;
            set;
        }

        public string PropertyActedOn
        {
            get;
            set;
        }
                
        public object PreviousState
        {
            get;
            set;
        }

        public CommandHistoryItem(string commandName)
            : this(commandName, null, "", null)
        { }

        public CommandHistoryItem(string commandName, UIElement elementActedOn,
            string propertyActedOn, object previousState)
        {
            CommandName = commandName;
            ElementActedOn = elementActedOn;
            PropertyActedOn = propertyActedOn;
            PreviousState = previousState;
        }
        public bool CanUndo
        {
            get { return (ElementActedOn != null && PropertyActedOn != ""); }
        }

        public void Undo()
        {
            Type elementType = ElementActedOn.GetType();
            PropertyInfo property = elementType.GetProperty(PropertyActedOn);
            property.SetValue(ElementActedOn, PreviousState, null);
        }
    }

CommandTarget指定目标后,目标元素的Command的怎么执行

例如,触发命令的源头

  Command="{x:Static local:CustomControlWithCommand.FontUpdateCommand}"
                                    CommandTarget="{Binding ElementName=txtBoxTarget}"
                                    CommandParameter="{Binding ElementName=FontSlider,
                                     Path=Value,
                                     Converter={StaticResource DoubleConverterResource}}"

接收元素

  <TextBox Name="txtBoxTarget" Height="100" Width="275" Margin="3">
              <TextBox.CommandBindings>
                <CommandBinding Command="{x:Static local:CustomControlWithCommand.FontUpdateCommand}"
                            Executed="SliderUpdateExecuted"
                            CanExecute="SliderUpdateCanExecute" />
              </TextBox.CommandBindings>              
              Hello
            </TextBox>
  public void SliderUpdateExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            TextBox source = sender as TextBox;

            if (source != null)
            {
                if (e.Parameter != null)
                {
                    try
                    {
                        if ((int)e.Parameter > 0 && (int)e.Parameter <= 60)
                        {
                            source.FontSize = (int)e.Parameter;
                        }
                    }
                    catch
                    {
                        MessageBox.Show("in Command \n Parameter: " + e.Parameter);
                    }

                }
            }
        }

        //The CanExecuteRoutedEvent Handler
        //if the Command Source is a TextBox, then set CanExecute to ture;
        //otherwise, set it to false
        public void SliderUpdateCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            TextBox source = sender as TextBox;

            if (source != null)
            {
                if (source.IsReadOnly)
                {
                    e.CanExecute = false;
                }
                else
                {
                    e.CanExecute = true;
                }
            }
        }

有的控件不支持Command,例如Slider,可以改写为CommandSlider : Slider, ICommandSource

基本DEMO

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

namespace Commands
{
    public class CommandSlider : Slider, ICommandSource
    {
        public CommandSlider()
            : base()
        {

        }

        //ICommand Interface Memembers
        //make Command a dependency property so it can be DataBound
        public static readonly DependencyProperty CommandProperty =
            DependencyProperty.Register(
                "Command",
                typeof(ICommand),
                typeof(CommandSlider),
                new PropertyMetadata((ICommand)null,
                new PropertyChangedCallback(CommandChanged)));

        public ICommand Command
        {
            get
            {
                return (ICommand)GetValue(CommandProperty);
            }
            set
            {
                SetValue(CommandProperty, value);
            }
        }
        //make CommandTarget a dependency property so it can be DataBound
        public static readonly DependencyProperty CommandTargetProperty =
            DependencyProperty.Register(
                "CommandTarget",
                typeof(IInputElement),
                typeof(CommandSlider),
                new PropertyMetadata((IInputElement)null));

        public IInputElement CommandTarget
        {
            get
            {
                return (IInputElement)GetValue(CommandTargetProperty);
            }
            set
            {
                SetValue(CommandTargetProperty, value);
            }
        }

        //make CommandParameter a dependency property so it can be DataBound
        public static readonly DependencyProperty CommandParameterProperty =
            DependencyProperty.Register(
                "CommandParameter",
                typeof(object),
                typeof(CommandSlider),
                new PropertyMetadata((object)null));

        public object CommandParameter
        {
            get
            {
                return (object)GetValue(CommandParameterProperty);
            }
            set
            {
                SetValue(CommandParameterProperty, value);
            }
        }

        // Command dependency property change callback
        private static void CommandChanged(DependencyObject d,
            DependencyPropertyChangedEventArgs e)
        {
            CommandSlider cs = (CommandSlider)d;
            cs.HookUpCommand((ICommand)e.OldValue, (ICommand)e.NewValue);
        }
        // Add a new command to the Command Property
        private void HookUpCommand(ICommand oldCommand, ICommand newCommand)
        {
            //if oldCommand is not null, then we need to remove the handlers
            if (oldCommand != null)
            {
                RemoveCommand(oldCommand, newCommand);
            }
            AddCommand(oldCommand, newCommand);
        }

        // Remove an old command from the Command Property
        private void RemoveCommand(ICommand oldCommand, ICommand newCommand)
        {
            EventHandler handler = CanExecuteChanged;
            oldCommand.CanExecuteChanged -= handler;
        }

        // add the command
        private void AddCommand(ICommand oldCommand, ICommand newCommand)
        {
            EventHandler handler = new EventHandler(CanExecuteChanged);
            canExecuteChangedHandler = handler;
            if (newCommand != null)
            {
                newCommand.CanExecuteChanged += canExecuteChangedHandler;
            }
        }
        private void CanExecuteChanged(object sender, EventArgs e)
        {

            if (this.Command != null)
            {
                RoutedCommand command = this.Command as RoutedCommand;

                // if RoutedCommand
                if (command != null)
                {
                    if (command.CanExecute(CommandParameter, CommandTarget))
                    {
                        this.IsEnabled = true;
                    }
                    else
                    {
                        this.IsEnabled = false;
                    }
                }
                // if not RoutedCommand
                else
                {
                    if (Command.CanExecute(CommandParameter))
                    {
                        this.IsEnabled = true;
                    }
                    else
                    {
                        this.IsEnabled = false;
                    }
                }
            }
        }

        //if Command is defined, then moving the slider will invoke the command;
        //otherwise, the silder will behave normally
        protected override void OnValueChanged(double oldValue, double newValue)
        {
            base.OnValueChanged(oldValue, newValue);

            if (this.Command != null)
            {
                RoutedCommand command = Command as RoutedCommand;

                if (command != null)
                {
                    command.Execute(CommandParameter, CommandTarget);
                }
                else
                {
                    ((ICommand)Command).Execute(CommandParameter);
                }
            }
        }

        //keep a copy of the handler so it doesn't get garbage collected
        private static EventHandler canExecuteChangedHandler;
    }
}

其他补充

关于后台设置16进制颜色为SolidBrush

BrushConverter converter = new BrushConverter();
            Brush newFill = (Brush)converter.ConvertFromString("#000000");
            e1.Fill = newFill;

版权声明:不允许一切网站转载  www.ayjs.net           aaronyang          Aaronyang技术分享

推荐您阅读更多有关于“WPF4.5,”的文章

猜你喜欢

额 本文暂时没人评论 来添加一个吧

发表评论

必填

选填

选填

必填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

  查看权限

抖音:wpfui 工作wpf,目前主maui

招聘合肥一枚WPF工程师,跟我一个开发组,10-15K,欢迎打扰

目前在合肥市企迈科技就职

AYUI8全源码 Github地址:前往获取

杨洋(AaronYang简称AY,安徽六安人)AY唯一QQ:875556003和AY交流

高中学历,2010年开始web开发,2015年1月17日开始学习WPF

声明:AYUI7个人与商用免费,源码可购买。部分DEMO不免费

不是从我处购买的ayui7源码,我不提供任何技术服务,如果你举报从哪里买的,我可以帮你转正为我的客户,并送demo

查看捐赠

AYUI7.X MVC教程 更新如下:

第一课 第二课 程序加密教程

标签列表