zoukankan      html  css  js  c++  java
  • WPF Demo19 命令、UC

    命令系统的基本元素和关系
    WPF命令系统的组成要素:
    A.命令(command):WPF命令实际上就是实习了ICommand接口的类。平时使用最多的就是RoutedCommand类。
    B.命令源(command source):即命令的发送者,实现了ICommandSource接口的类。
    C.命令目标(command Target):即命令发给了谁或理解为命令的接收者。命令目标必须是实现了IInputElement接口的类。
    D.命令关联(command Binding):负责把一些外围逻辑和命令关联起来。比如执行之前对命令是否可以执行进行判、命令执行之后还有哪些后续工作等。

    命令使用的步骤:
    1.创建命令类
    2.声明命名实例
    3.指定命令源
    4.指定命令目标
    5.设置命令关联

    ICommand接口与RoutedCommand
    WPF中的命令是实现了ICommand接口的类。
    ICommand接口非常简单,只包含两个方法一个事件。
    <1>Execute方法:命令执行,或者说命令执行于命令目标之上。需要注意的是,现实世界中的命令是不会自己执行的,而这里,执行变成了命令的方法,有点拟人化的味道。
    <2>CanExecute方法:在执行之前探知命令是否可以执行。
    <3>CanExecuteChanged事件:当命令的可执行状态改变的时候,可激发此事件通知其它对象。

    RoutedCommand就是一个实现了ICommand接口的类。
    RoutedCommand在实现ICommand接口时,并未向Execute和CanExecute方法中添加任何逻辑,
    也就是说,它是通用的、与具体的业务逻辑无关的。

    <Window x:Class="命令1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <StackPanel Background="Red" x:Name="sp1">
            <Button x:Name="btn1" Content="Send Clear Command" Margin="5" Background="{Binding}"/>
            <TextBox x:Name="txtA" Margin="5,0" Height="200"/>
        </StackPanel>
    </Window>
    using System.Windows;
    using System.Windows.Input;
    
    namespace 命令1
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
    
                InitializeCommand();
            }
    
            //1.创建命令类
            //2.声明命名实例
            //3.指定命令源—— 命令发送者
            //4.指定命令目标——命令接收者
            //5.设置命令关联
    
            //声明并定义命令   
            private RoutedCommand RouutedCommand = new RoutedCommand("可输入非空字符", typeof(MainWindow));
    
            private void InitializeCommand()
            {
                //把命令赋值给命令源,并定义快捷键   
                this.btn1.Command = RouutedCommand;
                this.RouutedCommand.InputGestures.Add(new KeyGesture(Key.C, ModifierKeys.Alt));
                //指定命令目标   
                this.btn1.CommandTarget = txtA;
    
                //创建命令关联   
                CommandBinding commandBinding = new CommandBinding();
                commandBinding.Command = RouutedCommand;//只关注与rouutedCommand相关的命令 
                commandBinding.CanExecute += new CanExecuteRoutedEventHandler(cb_CanExecute);
                commandBinding.Executed += new ExecutedRoutedEventHandler(cb_Execute);
                //把命令关联安置在外围控件上   
                this.sp1.CommandBindings.Add(commandBinding);
            }
    
            //当命令到达目标之后,此方法被调用   
            private void cb_Execute(object sender, ExecutedRoutedEventArgs e)
            {
                this.txtA.Clear();
                //避免事件继续向上传递而降低程序性能   
                e.Handled = true;
            }
    
            //当探测命令是否可执行的时候该方法会被调用   
            private void cb_CanExecute(object sender, CanExecuteRoutedEventArgs e)
            {
                if (string.IsNullOrEmpty(txtA.Text))
                {
                    e.CanExecute = false;
                }
                else
                {
                    e.CanExecute = true;
                }
                //避免事件继续向上传递而降低程序性能   
                e.Handled = true;
            }
        }
    }
    
    //对于以上的代码,需要注意以下几点:
    //第一,使用命令可以避免自己写代码判断Button是否可以用以及添加快捷键。
    
    //第二,RountedCommand是一个与业务逻辑无关的类,只负责在程序中跑腿而并不对命令目标进行操作,
    //TextBox并不是由它清空的。那么TextBox的情况操作是谁呢?答案是CommandBinding。
    //因为无论是探测命令是否可以执行还是命令送达目标,都会激发命令目标发送路由事件,
    //这些事件会沿着UI元素树向上传递,最终被CommandBinding所捕捉。
    //本例中CommandBinding被安装在外围的StackPanel上,Commandbinding站在高处起一个侦听器的作用,
    //而且专门针对rouutedCommand命令捕捉与其相关的事件。
    //本例中,当CommandBinding捕捉到CanExecute就会调用cb_CanExecute方法。
    //当捕捉到是Executed的时候,就调用cb_Execute事件。
    
    //第三,因为CanExecute事件的激发频率比较高,为了避免降低性能,在处理完毕之后建议将e.Handle设置为true。
    //第四,CommandBinding一定要设置在命令目标的外围控件上,不然无法捕捉CanExecute和Executed等路由事件。
    

    实例二:

    <Window x:Class="命令2.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="24" />
                <RowDefinition Height="4" />
                <RowDefinition Height="24" />
                <RowDefinition Height="4" />
                <RowDefinition Height="24" />
                <RowDefinition Height="4" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            
            <!--命令和命令参数-->
            <TextBlock  HorizontalAlignment="Left" Name="textBlock1" Text="Name:" VerticalAlignment="Center" Grid.Row="0"/>
            <TextBox x:Name="txtName" Margin="60,5,0,0" Grid.Row="0"/>
            <Button Content="New Teacher" Grid.Row="2" Command="New" CommandParameter="Teacher"/>
            <Button Content="New Student" Grid.Row="4" Command="New" CommandParameter="Student"/>
            <ListBox Grid.Row="6" x:Name="lbInfos"/>
        </Grid>
        
        <!--为窗体添加CommandBinding-->
        <Window.CommandBindings>
            <CommandBinding Command="New" CanExecute="CommandBinding_CanExecute" Executed="CommandBinding_Executed"/>
        </Window.CommandBindings>
    </Window>
    using System.Windows;
    using System.Windows.Input;
    
    namespace 命令2
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
            //两个按钮都使用的是New命令,但分别使用的是Student和Teacher做为的参数。
    
            public MainWindow()
            {
                InitializeComponent();
            }
    
            /// <summary>
            /// 当探测命令是否可执行的时候该方法会被调用
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
            {
                if (string.IsNullOrEmpty(txtName.Text))
                {
                    e.CanExecute = false;
                }
                else
                {
                    e.CanExecute = true;
                }
                //路由终止,提高系统性能   
                e.Handled = true;
            }
    
            /// <summary>
            /// 当命令到达目标之后,此方法被调用   
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
            {
                if (e.Parameter.ToString() == "Student")
                {
                    this.lbInfos.Items.Add(string.Format("New Student:{0} 好好学习,天天向上。", txtName.Text));
                }
                else if (e.Parameter.ToString() == "Teacher")
                {
                    this.lbInfos.Items.Add(string.Format("New Teacher:{0} 学而不厌,诲人不倦。", txtName.Text));
                }
                //路由终止,提高系统性能   
                e.Handled = true;
            }  
        }
    }
    

    实例三:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace 命令4
    {
        public interface IView
        {
            //属性   
            bool IsChanged { get; set; }
            //方法   
            void SetBinding();
            void Refresh();
            void Clear();
            void Save();
        }
    }
    
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Input;
    
    namespace 命令4
    {
        public class ClearCommand : ICommand
        {
            //当命令可执行状态发送改变时,应当被激发   
            public event EventHandler CanExecuteChanged;
    
            //用来判断命令是否可以执行   
            public bool CanExecute(object parameter)
            {
                throw new NotImplementedException();
            }
    
            //命令执行时,带有与业务相关的Clear逻辑   
            public void Execute(object parameter)
            {
                IView view = parameter as IView;
                if (view != null)
                {
                    view.Clear();
                }
            }
        }
    }
    
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Controls;
    using System.Windows.Input;
    using System.Windows;
    
    namespace 命令4
    {
        public class MyCommandSource : UserControl, ICommandSource
        {
            /// <summary>   
            /// 继承自ICommand的3个属性   
            /// </summary>   
            public ICommand Command
            {
                get;
                set;
            }
    
            public object CommandParameter
            {
                get;
                set;
            }
    
            public IInputElement CommandTarget
            {
                get;
                set;
            }
    
            //在命令目标上执行命令,或者说让命令作用于命令目标   
            protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
            {
                base.OnMouseLeftButtonDown(e);
                if (this.CommandTarget != null)
                {
                    this.Command.Execute(CommandTarget);
                }
            }
        }
    }
    
    <UserControl x:Class="命令4.UCMniView"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        <Border CornerRadius="5" BorderBrush="GreenYellow" BorderThickness="2">
            <StackPanel>
                <TextBox Margin="5" x:Name="txt1"></TextBox>
                <TextBox Margin="5" x:Name="txt2"></TextBox>
                <TextBox Margin="5" x:Name="txt3"></TextBox>
                <TextBox Margin="5" x:Name="txt4"></TextBox>
            </StackPanel>
        </Border>
    
    </UserControl>
    using System;
    using System.Windows.Controls;
    
    namespace 命令4
    {
        /// <summary>
        /// UserControl.xaml 的交互逻辑
        /// </summary>
        public partial class UCMniView : UserControl,IView
        {
            public UCMniView()
            {
                InitializeComponent();
            }
    
            public bool IsChanged
            {
                get
                {
                    throw new NotImplementedException();
                }
                set
                {
                    throw new NotImplementedException();
                }
            }
    
            public void SetBinding()
            {
                throw new NotImplementedException();
            }
    
            public void Refresh()
            {
                throw new NotImplementedException();
            }
    
            public void Clear()
            {
                this.txt1.Clear();
                this.txt2.Clear();
                this.txt3.Clear();
                this.txt4.Clear(); 
            }
    
            public void Save()
            {
                throw new NotImplementedException();
            }
        }
    }
    
    <Window x:Class="命令4.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:命令4"
            Title="MainWindow" Height="350" Width="525">
        <StackPanel>
            <local:MyCommandSource x:Name="myCommandSource1">
                <TextBlock Text="清除" Width="80" FontSize="16" TextAlignment="Center" Background="LightGreen"/>
            </local:MyCommandSource>
    
            <local:UCMniView x:Name="mniView1" />
        </StackPanel>
    
    </Window>
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace 命令4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
    
                ClearCommand clearCommand = new ClearCommand();
                this.myCommandSource1.Command = clearCommand;
                this.myCommandSource1.CommandTarget = mniView1;  
            }
        }
    }
    

  • 相关阅读:
    LeetCode——加油站
    LeetCode——分发糖果
    LeetCode——单词拆分 ii
    LeetCode—— 单词拆分
    LeetCode——重排链表
    IAR ARM、IAR STM8、IAR MSP430共用一个IDE
    OSAL多任务资源分配机制
    Win7系统Matlab2013a安装.m文件不自动关联到MATLAB.exe解决方法
    Java SE/ME/EE的概念介绍
    STL,ATL,WTL之间的联系和区别
  • 原文地址:https://www.cnblogs.com/YYkun/p/6873412.html
Copyright © 2011-2022 走看看