- 浏览: 401189 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (309)
- xaml C# wpf (0)
- scala java inner clas (1)
- Tools UML Eclipse UML2 (1)
- Timer .NET Framework (1)
- perl (6)
- python function paramter (1)
- Python Docstring (1)
- Python how to compare types (1)
- Python (8)
- java (5)
- C# (76)
- C# WPF (0)
- p4 (0)
- WPF (46)
- .net (6)
- xaml (1)
- javascript (40)
- windows (10)
- scala (4)
- winform (1)
- c++ (48)
- tools (12)
- cmd (1)
- os (0)
- CI (0)
- shell (0)
- C (2)
- haskell (49)
- functional (1)
- tool (1)
- gnu (1)
- linux (1)
- kaskell (0)
- svn (0)
- wcf (3)
- android (1)
最新评论
It is always useful to have some common stereotype/boilerplate so that you can copy and paste and start something every quickly.
This is for RoutedCommand stenciles/templates.
there are three major steps involves with the RoutedCommand;
they are
- Declare/Define/Create the routed Command
- Set the Command property a Control can raise/trigger, e.g. <Button Command=...>
- Add/Remove the handler to the RoutedCommand, through the use CommandBinding
In the following example, we are going to create Custom RoutedCommand, and we are going to give it name "OKCommand";
The RoutedComand Static Field Approach
Since in Xaml the CommandBinding's Command Property is a static field, you could not use a Binding Element on the Command attribute of CommandBindings;
So it is recommended to use Static Field for the RoutedCommands;
private static RoutedCommand m_okCommand; public static RoutedCommand OKCommand { get { return m_okCommand != null ? m_okCommand : (m_okCommand = new RoutedCommand("OKCommand", typeof(MainWindow))); } }
and you use the x:Static Xaml directive to pick up the ICommand
<Button x:Name="OKButton" IsDefault="True" Content="OK" Command="{x:Static local:MainWindow.OKCommand}" CommandTarget="{Binding RelativeSource={RelativeSource Self}}"> <Button.CommandBindings> <CommandBinding Command="{x:Static local:MainWindow.OKCommand}" CanExecute="OKCommandCanExecute" Executed="OKCommandExecuted" > </CommandBinding> </Button.CommandBindings> <Button.InputBindings> <KeyBinding Gesture="Alt+O" Command="{x:Static local:MainWindow.OKCommand}"> </KeyBinding> </Button.InputBindings> </Button>
Except setting the command bindings through the use of Xaml, you can also do it via code inside the CLR code. Below is one example.
public MainWindow() { InitializeComponent(); this.CommandBindings.Add(new CommandBinding( OKCommand, OKCommandExecuted, OKCommandCanExecute) ); }
As you can see, this is the most common way of using the RoutedCommand.
A slightly better way is to move the RoutedCommand out of the MainWindow and put into a separate class which can be shared by many classes.
Following the discussion, we will move the commands to another class called Commands;
namespace AcceptOrCancelButton { public class Commands : DependencyObject { private static RoutedCommand m_okCommand; public static RoutedCommand OKCommand { get { return m_okCommand != null ? m_okCommand : (m_okCommand = new RoutedCommand("OKCommand", typeof(MainWindow))); } } } }
The Dependency Property approach
DependencyProperty the key is a public static readonly field, the metadata is associated with the owner class as well, but the CLR accessor is associated with the class intance, and this is creating a issue for us iin Xaml.
Suppose now the Commands class is like this:
namespace AcceptOrCancelButton { public class Commands : DependencyObject { public RoutedCommand OKCommand { get { return (RoutedCommand)GetValue(OKCommandProperty); } set { SetValue(OKCommandProperty, value); } } // Using a DependencyProperty as the backing store for OKCommand. This enables animation, styling, binding, etc... public static readonly DependencyProperty OKCommandProperty = DependencyProperty.Register("OKCommand", typeof(RoutedCommand), typeof(Commands), new UIPropertyMetadata(new RoutedCommand("OKCommand", typeof(Commands)))); } }
In xaml , the following won't work.
<Window x:Class="AcceptOrCancelButton.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:AcceptOrCancelButton" x:Name="Self" > <Window.CommandBindings> <CommandBinding Command="{Binding Path=OKCommand, ElementName=Self}" CanExecute="OKCommandCanExecute" Executed="OKCommandExecuted" > </CommandBinding> </Window.CommandBindings> </Window>
You will see the following error at runtime.
A 'Binding' cannot be set on the 'Command' property of type 'CommandBinding'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.
however, you can still use the code to do the bindings;
namespace AcceptOrCancelButton { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); this.CommandBindings.Add(new CommandBinding( Commands.OKCommand, OKCommandExecuted, OKCommandCanExecute) ); } private Commands m_commands = new Commands(); public Commands Commands { get { return m_commands; } } } }
the UIElement do has the Command as DependencyProperty, so that you can do the following.
<Button x:Name="OKButton" IsDefault="True" Content="OK" Command="{Binding Path=Commands.OKCommand, ElementName=Self}" CommandTarget="{Binding RelativeSource={RelativeSource Self}}"> <Button.InputBindings> <KeyBinding Gesture="Alt+O" Command="{Binding Path=Commands.OKCommand, ElementName=Self}"> </KeyBinding> </Button.InputBindings> </Button>
However, if you do want to achieve this in Xaml (if you are paranoid for no reason).
the key is the StaticResource
<Window x:Class="AcceptOrCancelButton.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:AcceptOrCancelButton" Title="MainWindow" Height="350" Width="525" x:Name="Self" > <Window.Resources> <RoutedCommand x:Key="MyCommand" /> <local:Commands x:Key="Commands" OKCommand="{StaticResource MyCommand}" > <!--<local:Commands.OKCommand> <StaticResource ResourceKey="MyCommand"></StaticResource> </local:Commands.OKCommand>--> </local:Commands> </Window.Resources> <StackPanel> <!-- With the help of Click Event, prove cancel and default button works --> <!--<Button x:Name="OKButton" IsDefault="True" Content="OK" Click="OkClick"/> <Button x:Name="CancelButton" IsCancel="True" Content="Cancel" Click="CancelClick"/>--> <!-- With the help of Static Routed Comand, prove cancel and default button works --> <Button x:Name="OKButton" IsDefault="True" Content="OK" Command="{StaticResource MyCommand}" CommandTarget="{Binding RelativeSource={RelativeSource Self}}"> <Button.CommandBindings> <CommandBinding Command="{StaticResource MyCommand}" CanExecute="OKCommandCanExecute" Executed="OKCommandExecuted" > </CommandBinding> </Button.CommandBindings> <Button.InputBindings> <KeyBinding Gesture="Alt+O" Command="{StaticResource MyCommand}"> </KeyBinding> </Button.InputBindings> </Button> </StackPanel> </Window>
You can only use StaticResource, you cannot use DynamicResource, because DynamicResource requires that the target property is a DependencyProperty;
Tricks to use AttachedDependencyProperty
You can create a Attached Dependency Property,which indicate if the element that the attached property is applied will be bound to a known RoutedCommand (in this example), the known RoutedCommand is the defined in the Resources.
here is the code.
public static bool GetIsOKCommandSource(DependencyObject obj) { return (bool)obj.GetValue(IsOKCommandSourceProperty); } public static void SetIsOKCommandSource(DependencyObject obj, bool value) { obj.SetValue(IsOKCommandSourceProperty, value); } // Using a DependencyProperty as the backing store for IsOKCommandSource. This enables animation, styling, binding, etc... public static readonly DependencyProperty IsOKCommandSourceProperty = DependencyProperty.RegisterAttached("IsOKCommandSource", typeof(bool), typeof(MainWindow), new UIPropertyMetadata(false, OnIsOkCommandSourceChanged)); public static void OnIsOkCommandSourceChanged(DependencyObject dep, DependencyPropertyChangedEventArgs e) { if ((bool)e.NewValue == true) { //Button button = dep as Button; Button button = dep as Button; if (button != null) { var command = ((Commands)button.TryFindResource("Commands")).OKCommand; button.Command = command; button.CommandTarget = button; } } }
and you have the following xaml which basically create the resource, create the Command handlers, and use the attach dependency property.
<Window x:Class="AcceptOrCancelButton.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:AcceptOrCancelButton" Title="MainWindow" Height="350" Width="525" x:Name="Self" > <Window.Resources> <RoutedCommand x:Key="MyCommand" /> <local:Commands x:Key="Commands" OKCommand="{StaticResource MyCommand}" > </local:Commands> </Window.Resources> <Window.CommandBindings> <CommandBinding Command="{StaticResource MyCommand}" CanExecute="OKCommandCanExecute" Executed="OKCommandExecuted" > </CommandBinding> </Window.CommandBindings> <StackPanel> <Button x:Name="OKButton" local:MainWindow.IsOKCommandSource="True" IsDefault="True" Content="OK"> </Button> </StackPanel> </Window>
Another way to use the Attached Dependency Property is as follow. -- this is not IDEAL, tend to remove
public static RoutedCommand GetOkCommand(DependencyObject obj) { return (RoutedCommand)obj.GetValue(OkCommandProperty); } public static void SetOkCommand(DependencyObject obj, RoutedCommand value) { obj.SetValue(OkCommandProperty, value); } // Using a DependencyProperty as the backing store for OkCommand. This enables animation, styling, binding, etc... public static readonly DependencyProperty OkCommandProperty = DependencyProperty.RegisterAttached("OkCommand", typeof(RoutedCommand), typeof(MainWindow), new UIPropertyMetadata(null, OnOKCommandChanged)); public static void OnOKCommandChanged(DependencyObject dep, DependencyPropertyChangedEventArgs e) { if (e.NewValue != null) { if (dep is ICommandSource) { var parent = GetParent(dep, typeof(MainWindow)) as MainWindow; if (dep.GetType() == typeof(Button)) { Button button = (Button)dep; button.Command = (RoutedCommand)e.NewValue; button.CommandTarget = button; button.CommandBindings.Add(new CommandBinding(button.Command, parent.OKCommandExecuted, parent.OKCommandCanExecute)); } } } } public static DependencyObject GetParent(DependencyObject obj, Type parentType) { DependencyObject parent = obj ; if (obj == null) return null; Type type = obj.GetType(); while (type != parentType) { parent = LogicalTreeHelper.GetParent(parent); if (parent != null) type = parent.GetType(); else return null; } return parent; }
and the xaml
<Window x:Class="AcceptOrCancelButton.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:AcceptOrCancelButton" Title="MainWindow" Height="350" Width="525" x:Name="Self" > <Window.Resources> <RoutedCommand x:Key="MyCommand" /> <local:Commands x:Key="Commands" OKCommand="{StaticResource MyCommand}" > </local:Commands> </Window.Resources> <StackPanel> <Button x:Name="OKButton" local:MainWindow.OkCommand="{Binding Source={StaticResource MyCommand}}" IsDefault="True" Content="OK" /> </StackPanel> </Window>
The last attached event I am thinking of is of type CommandBinding; Please see below.
public static CommandBinding GetOKCommandBinding(DependencyObject obj) { return (CommandBinding)obj.GetValue(OKCommandBindingProperty); } public static void SetOKCommandBinding(DependencyObject obj, CommandBinding value) { obj.SetValue(OKCommandBindingProperty, value); } // Using a DependencyProperty as the backing store for OKCommandBinding. This enables animation, styling, binding, etc... public static readonly DependencyProperty OKCommandBindingProperty = DependencyProperty.RegisterAttached("OKCommandBinding", typeof(CommandBinding), typeof(MainWindow), new UIPropertyMetadata(null, OnOKCommandBindingChanged)); public static void OnOKCommandBindingChanged(DependencyObject dep, DependencyPropertyChangedEventArgs e) { if (e.NewValue != null) { if (dep.GetType() == typeof(Button)) { var button = (Button)dep; button.CommandBindings.Clear(); button.CommandBindings.Add((CommandBinding)e.NewValue); } } }
and the Xaml
<Window x:Class="AcceptOrCancelButton.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:AcceptOrCancelButton" Title="MainWindow" Height="350" Width="525" x:Name="Self" > <Window.Resources> <RoutedCommand x:Key="MyCommand" /> <local:Commands x:Key="Commands" OKCommand="{StaticResource MyCommand}" > </local:Commands> <CommandBinding x:Key="OKCommandBinding" Command="{StaticResource MyCommand}" Executed="OKCommandExecuted" CanExecute="OKCommandCanExecute" > </CommandBinding> </Window.Resources> <StackPanel> <Button x:Name="OKButton" local:MainWindow.OKCommandBinding="{StaticResource OKCommandBinding}" Command="{StaticResource MyCommand}" IsDefault="True" Content="OK" /> </StackPanel> </Window>
发表评论
-
wpf - example to enhance ComboBox for AutoComplete
2014-09-19 15:56 1979first let’s see an example ... -
WPF – Virtualization – VirutalizationStackPanel and ItemsPanelTemplate
2013-08-05 21:55 1422Topic: WPF – Virtualization – ... -
wpf - BehaviorBase and one use examples
2013-06-18 18:41 1318Behavior is something that we ... -
WPF - Setting foreground color of Entire window
2013-06-13 16:00 1925You might as well as I would s ... -
WPF - Enhanced TabControl - TabControlEx aka Prerendering TabControl
2013-06-13 13:12 5337As an opening word, let's che ... -
wpf - ControlTemplate and AddLogicChild/RemoveLogicalChild
2013-06-10 15:42 1191Recently I was trying to debug ... -
wpf - default implicit style
2013-05-10 10:24 796We know that if you left out ... -
wpf - Style setter on the attached property
2013-05-08 14:54 2858I believe that you are familia ... -
wpf - specify enum values in xaml
2013-05-08 11:31 3594Many a situation you find tha ... -
wpf - IG xamDataGrid bind to XmlDataProvider with Xml Island
2012-12-18 14:28 1290Sometimes you may bind to some ... -
wpf - translate winform button/mouse event to wpf events
2012-12-12 17:37 2166It is common that we sometimes ... -
wpf - Freezable and its meaning
2012-09-27 12:38 0This article is based on the di ... -
wpf - Customize the grid lines for original wpf Grid control
2012-09-27 12:01 1461The System.WIndows.Controls.Gri ... -
c# - Convert from System.Drawing.Image to System.WIndows.Media.ImageSource
2012-09-25 14:27 7421In Previous discussion, we have ... -
wpf - Get Effective DependencyProperty value on a DependencyObject
2012-08-28 19:05 1048As discussed in my previous pos ... -
wpf - Default(Theme) style and its DefaultStyleKey
2012-08-28 17:54 1392As dicsused in the subsection o ... -
wpf - Dependency Property Value Precedence
2012-08-28 18:56 886A dependency property to an Dep ... -
wpf - WPF TemplateBinding vs RelativeSource TemplatedParent
2012-08-28 14:20 3719This is a post that summarizes ... -
wpf - ICutomTypeDescriptor , PropertyDescriptor and its use in PropertyGrid
2012-08-28 14:04 3589The type ICustomTypeDe ... -
wpf - tips to convert UI controls in WPF/Silverlight/Winforms into a Bitmap
2012-08-27 17:44 987In previous discussion, we have ...
相关推荐
gong-wpf-dragdrop, GongSolutions.WPF.DragDrop 库是WPF的拖动'n'拖放框架 简介GongSolutions.WPF.DragDrop 库是一个易于使用的拖拉'n'拖放框架。特性使用 MVVM: 拖放逻辑可以放在ViewModel中。 代码不需要放在in中...
通用WPF主题控件包rubyer-wpf-master是一款专为Windows Presentation Foundation (WPF) 应用程序设计的开源UI框架。它提供了丰富的主题和控件,旨在帮助开发者快速构建美观且用户友好的应用程序界面。在2.0.0版本中...
标题中的“wpf-mvvm-DeskTop-Sample-master”表明这是一个关于WPF(Windows Presentation Foundation)桌面应用程序的示例项目,使用了MVVM(Model-View-ViewModel)设计模式。这个项目是用C#编程语言编写的,面向的...
**WPF-Blockly** 是一个基于Windows Presentation Foundation (WPF) 的图形化编程工具,它为用户提供了构建和设计程序的直观界面。WPF作为Microsoft .NET Framework的一部分,主要用于构建桌面应用程序,它提供了...
C#开发WPF-Silverlight动画及游戏系列教程-深蓝色右手 C#开发WPF-Silverlight动画及游戏系列教程-深蓝色右手 C#开发WPF-Silverlight动画及游戏系列教程-深蓝色右手
在这个名为"WPF-ControlBase-master.zip"的压缩包中,我们可以推测它包含了一个基于WPF的控制库项目,可能是一个开源或者个人开发的项目,用于提供自定义的WPF控件。这些控件可能是对标准WPF控件的扩展或增强,也...
WPF的基本空间历程,使用.net core3.0.1版本
【标题】"基于WPF的图形化编程控件和环境WPF-Blockly-master" 提供了一个创新的编程体验,它将传统的代码编写转变为图形化的流程图形式,使得编程变得更加直观和易于理解。WPF(Windows Presentation Foundation)是...
Bootstrap-WPF 样式是一种将流行的前端框架 Bootstrap 的设计风格应用于 WPF(Windows Presentation Foundation)应用程序的方法。Bootstrap 是一个广泛使用的开源工具包,主要用于构建响应式、移动设备优先的网页...
【标题】"WPF-JJDown-v1.234.0" 提示我们这是一个基于Windows Presentation Foundation(WPF)的应用程序,名为JJDown。版本号v1.234.0表明这是该软件的第1次重大更新,第234次次要更新或修复。这通常意味着它经历了...
通过深入研究WPF-Diagram-Designer的源代码(如WPF-Diagram-Designer-master文件夹中的内容),开发者不仅可以学习到如何在WPF中构建复杂的图形界面,还可以了解到图形编辑器的设计原理和实现细节,对于提升图形应用...
在本文中,我们将深入探讨"AI-wpf-controls",这是一个专为Windows Presentation Foundation(WPF)框架设计的控件库。这个独特的库整合了多个知名控件库的优点,包括MahApps.Metro、Material-Design、HandyControl...
在本项目"WPF-MaterialDesign-master.zip"中,重点在于利用**Material Design**这一设计语言来增强WPF应用的视觉效果。Material Design是Google推出的一种设计规范,其灵感来源于现实世界中的纸张和墨水,强调层次感...
在“Wpf-glTF-testing.zip”压缩包中,我们有一个基于WPF(Windows Presentation Foundation)的简化glTF文件查看器项目。 WPF是.NET Framework的一部分,是一个用于构建Windows桌面应用程序的框架。它提供了丰富的...
**WPF - 强大的图表技术** Windows Presentation Foundation (WPF) 是Microsoft开发的一个用于构建桌面应用程序的框架,它提供了丰富的图形系统,包括对2D和3D图形的强大支持。在WPF中,开发人员可以利用各种图表...
【标题】"Wpf的Diagram画板aistudio-wpf-diagram-master" 是一个基于WPF(Windows Presentation Foundation)技术的图形设计工具,用于创建和编辑图表或流程图。这个项目是在原有的WPF-Diagram-Designer基础上进行的...
《OpenControls.Wpf-master:深度探索WPF框架控件》 在Windows Presentation Foundation(WPF)的世界里,开发者们能够创建出美观且功能丰富的桌面应用程序。OpenControls.Wpf-master项目,正如其名,是一个专注于...
“wpf---StatusBar”这个标题表明我们将探讨的是WPF(Windows Presentation Foundation)框架中的StatusBar组件。WPF是.NET Framework的一部分,用于构建桌面应用程序,它提供了丰富的用户界面(UI)功能。StatusBar...
在这个“wpf-datagrid-access DB”主题中,我们将深入探讨如何利用WPF Datagrid与Microsoft Access数据库进行交互,实现数据的读取、更新和保存。 1. **WPF Datagrid简介** - Datagrid是WPF中的一个数据展示控件,...
C#开发WPF-Silverlight动画及游戏系列教程-深蓝色右手 C#开发WPF-Silverlight动画及游戏系列教程-深蓝色右手 C#开发WPF-Silverlight动画及游戏系列教程-深蓝色右手