Continue to chat about WPF-custom commands

Source: Internet
Author: User

 

As the last technology before Spring FestivalArticleWhat do you want to write? For a moment, let's talk about the commands in WPF. The command is very interesting. In short, it is a logic, but this logic can be called by multiple origins and can be applied to multiple targets. For example, Common commands such as "copy" and "cut" are logical operations on the clipboard. However, you will find that, they can be used not only in menu items, but also in toolbar buttons, or by pressing CTRL + C.

Menu item

Toolbar button

From the above example, we can find that commands can useCodeThe logic becomes generic, just as we encapsulate a class and can be called in N places, so we don't have to write the same code every time.

 

. The net class library has prepared many general commands for us, which are also very simple to use. Here we will not talk about them. You can refer to the relevant instructions on msdn. The topic of this article is custom commands, before talking about custom commands, let's take a look at several elements related to commands. Just like the "six elements of narrative", a complete command should include:

1. commands. This is of course the core part;

2. Command Source: Who issued the command;

3. Target: the elements on which the command works. For example, if the content is pasted into the text box, the textbox is the command target;

 

Strictly speaking, commands are classes that implement the icommand interface. However, in actual use, we do not have to do this, an effective method is to directly declare a routecommand class member field in a class. Generally, the static keyword is used, so that the command is only related to the class, you don't have to worry about which instance it belongs.

Next, let's create an instance:

1. Create a WPF ApplicationProgram, How to create? (Omitted );

2. layout of the main form. We need two text boxes and a button, which others like;

3. Use commadbinding to add the command to the commandbindings set of the Form class.

4. Set the command attribute on the button.

<Window X: class = "commandsample. mainwindow "xmlns =" http://schemas.microsoft.com/winfx/2006/xaml/presentation "xmlns: x =" http://schemas.microsoft.com/winfx/2006/xaml "xmlns: c =" CLR-namespace: commandsample "Title =" command example "Height =" 100 "width =" 300 "> <! -- Add command binding --> <window. commandbindings> <commandbinding command = "{X: static C: mainwindow. mycommand} "canexecute =" mycmd_canexecute "executed =" mycmd_executed "/> </window. commandbindings> <grid. rowdefinitions> <rowdefinition Height = "Auto"/> <rowdefinition Height = "Auto"/> </grid. rowdefinitions> <stackpanel orientation = "horizontal" grid. row = "0" Height = "25" margin = ","> <textbox X: Name = "txt01" margin =, 120 "text =" text box 1 "width =" "/> <textbox X: Name =" txt02 "margin =, 120 "text =" text box 2 "width =" "/> </stackpanel> <button X: Name =" btntest "grid. row = "1" margin = "80, 5, 80, 0" Height = "25" content = "run the command" command = "{X: static C: mainwindow. mycommand} "/> </GRID> </WINDOW>

in the above XAML, note that, we want to introduce the namespace of the class that defines the routing command. next, we need to write two Event Handlers -- canexecute to determine whether the command is available; the executed command logic should be written here.

 // command public static routedcommand mycommand = new routedcommand (); Public mainwindow () {initializecomponent ();} private void mycmd_canexecute (Object sender, canexecuteroutedeventargs e) {If (E. source! = NULL) {e. canexecute = true;} else {e. canexecute = false;} private void mycmd_executed (Object sender, executedroutedeventargs e) {If (E. Source! = NULL) {var target = E. source as control; If (target! = NULL) {If (target. foreground = brushes. blue) {target. foreground = brushes. black;} else {target. foreground = brushes. blue ;}}}

In this way, we will have a question: who is the initiator of the event? Who is the command target?

We place a breakpoint at the beginning of the executed event processing program, and then follow in one step.

The result is as follows:

Sender is the main form.

 

The source attribute of executedroutedeventargs is the command target.

However, when we run it, we find that the font turns blue instead of a text box, but a button. Why?

After carefully reading the msdn document and related instructions, we can see that, because we have not set the target, by default, the element that gets the focus will become the Command target.

Next we will change the above XAML to point the commandtarget of the button to the second text box.

<Button X: Name = "btntest" grid. row = "1" margin = "80, 5, 80, 0" Height = "25" content = "run the command" command = "{X: static C: mainwindow. mycommand} "commandtarget =" {binding elementname = txt02} "/>

Now, you can see that after you click the button, the foreground color of the second text box becomes blue.

Both the canexecute and executed events are routing events. Of course, the routecommand class also contains Channel Events. What is a routing event and what is a channel event is not covered in this article.

Take routing events as an example. The second example is given below. In this example, there is a stackpanel in the form that contains a button. At the same time, the commandbinding is added to the stackpanel, and a dockpanel is nested in the stackpanel. Similarly, add the same command to the dockpanel. The dockpanel contains a canvas, but the canvas does not add a commandbinding. Then, the types of events triggered are output in the executed event handler, the value of the name attribute of the Command target type and target.

 

[XAML]

<Window X: class = "cmd_smpl2.window1" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns: x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns: c = "CLR-namespace: performance_smpl2 "Title =" window1 "Height =" 300 "width =" 300 "> <grid> <stackpanel orientation =" vertical "> <stackpanel. commandbindings> <commandbinding command = "{X: static C: window1.mycmdroute}" canexecute = "cmd_canexecutehandler" executed = "cmd_executedhandler"/> </stackpanel. commandbindings> <button X: Name = "btntest1" width = "100" Height = "25" content = "Execute Command 1" command = "{X: static C: window1.mycmdroute} "/> <dockpanel. commandbindings> <commandbinding command = "{X: static C: window1.mycmdroute}" canexecute = "cmd_canexecutehandler" executed = "cmd_executedhandler"/> </dockpanel. commandbindings> <button X: Name = "btntest2" dockpanel. dock = "TOP" content = "Run Command 2" command = "{X: static C: window1.mycmdroute}"/> <canvas> <button X: Name = "btntest3" canvas. top = "3" canvas. left = "5" width = "100" Height = "25" content = "Run Command 3" command = "{X: static C: window1.mycmdroute} "/> </canvas> </dockpanel> </stackpanel> </GRID> </WINDOW>

[C # code]

Public static routedcommand mycmdroute = new routedcommand (); Public window1 () {initializecomponent ();} private void cmd_canexecutehandler (Object sender, canexecuteroutedeventargs e) {e. canexecute = E. source = NULL? False: true;} private void pai_executedhandler (Object sender, executedroutedeventargs e) {If (E. Source! = NULL & sender! = NULL) {string MSG = "Event Type: {0}, Command target type: {1}, Command target name: {2}"; system. diagnostics. debug. writeline (string. format (MSG, sender. getType (). name, E. source. getType (). name, (E. source as frameworkelement ). name ));}}

Then, run the program, click the three buttons in turn, and then open the "output" window to observe.

The result is as follows:

 
Type of the event to be triggered: stackpanel; type of the Command target: button; Name of the Command target: btntest1; type of the event to be triggered: dockpanel; type of the Command target: button; Name of the Command target: type of the event triggered by btntest2: dockpanel, type of the Command target: button, name of the Command target: btntest3

What have you found? From the debugging information, we can see that the type of the events that are triggered by the last two commands is dockpanel, which also conforms to the principle that the routing events bubble up along the visualization tree.

Because no commands are bound to the canvas, events cannot be triggered on the canvas. Therefore, the events are routed up to the dockpanel. Therefore, the trigger of the last two events is the dockpanel.

 

Next, we also need to do the third example. The example uses the shortcut key CTRL + ALT + Y instead of the control to execute the command.

Public partial class window1: window {public static routedcommand mycmd = new routedcommand (); Public window1 () {initializecomponent (); // bind the event commandmanager. addcanexecutehandler (this, this. cmd_canexehandler); commandmanager. addexecutedhandler (this, this. cmd_exehandler); // bind the command this. inputbindings. add (New keybinding (mycmd, key. y, modifierkeys. control | modifierkeys. ALT);} private void pai_ca Nexehandler (Object sender, canexecuteroutedeventargs e) {e. canexecute = true;} private void cmd_exehandler (Object sender, executedroutedeventargs e) {MessageBox. Show ("Command executed. ");}}

Run the program. When the window is active, press CTRL + ALT + Y to see the effect.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.