以我的经验来说,要让TemplatedControl支持Command的需求不会很多,大部分情况用附加属性解决这个需求会更便利些,譬如UWPCommunityToolkit的HyperlinkExtensions。

如果正在从头设计自定义控件并真的需要提供命令支持,可以参考这篇文章。支持Command的步骤比较简单,所以这篇文章比较简短。

要实现Command支持,控件中要执行如下步骤:

  • 定义Command和CommandParameter属性。
  • 监视Command的CanExecuteChanged事件。
  • 在CanExecuteChanged的事件处理函数及CommandParameter的PropertyChangedCallback中,根据Command.CanExecute(CommandParameter)的结果设置控件的IsEnabled属性。
  • 在某个事件(Click或者ValueChanged)中执行Command。

MenuItem是实现了Command支持的示例,重载了OnPointerPressed并且在其中执行Command:

public class MenuItem : Control
{
/// <summary>
/// 标识 Command 依赖属性。
/// </summary>
public static readonly DependencyProperty CommandProperty =
DependencyProperty.Register("Command", typeof(ICommand), typeof(MenuItem), new PropertyMetadata(null, OnCommandChanged)); private static void OnCommandChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
MenuItem target = obj as MenuItem;
ICommand oldValue = (ICommand)args.OldValue;
ICommand newValue = (ICommand)args.NewValue;
if (oldValue != newValue)
target.OnCommandChanged(oldValue, newValue);
} /// <summary>
/// 标识 CommandParameter 依赖属性。
/// </summary>
public static readonly DependencyProperty CommandParameterProperty =
DependencyProperty.Register("CommandParameter", typeof(object), typeof(MenuItem), new PropertyMetadata(null, OnCommandParameterChanged)); private static void OnCommandParameterChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
MenuItem target = obj as MenuItem;
object oldValue = (object)args.OldValue;
object newValue = (object)args.NewValue;
if (oldValue != newValue)
target.OnCommandParameterChanged(oldValue, newValue);
} public MenuItem()
{
this.DefaultStyleKey = typeof(MenuItem);
} public event RoutedEventHandler Click; /// <summary>
/// 获取或设置Command的值
/// </summary>
public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
} /// <summary>
/// 获取或设置CommandParameter的值
/// </summary>
public object CommandParameter
{
get { return (object)GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
} protected virtual void OnCommandParameterChanged(object oldValue, object newValue)
{
UpdateIsEnabled();
} protected virtual void OnCommandChanged(ICommand oldValue, ICommand newValue)
{
if (oldValue != null)
oldValue.CanExecuteChanged -= OnCanExecuteChanged; if (newValue != null)
newValue.CanExecuteChanged += OnCanExecuteChanged; UpdateIsEnabled();
} protected virtual void UpdateVisualState(bool useTransitions)
{
if (IsEnabled)
{
VisualStateManager.GoToState(this, "Normal", useTransitions);
}
else
{
VisualStateManager.GoToState(this, "Disabled", useTransitions);
}
} protected override void OnPointerPressed(PointerRoutedEventArgs e)
{
base.OnPointerPressed(e);
Click?.Invoke(this, new RoutedEventArgs());
if ((null != Command) && Command.CanExecute(CommandParameter))
{
Command.Execute(CommandParameter);
}
} private void OnCanExecuteChanged(object sender, EventArgs e)
{
UpdateIsEnabled();
} private void UpdateIsEnabled()
{
IsEnabled = (null == Command) || Command.CanExecute(CommandParameter);
UpdateVisualState(true);
}
}

以下是使用示例,作用是当TextBox的Text不为空时可以点击MenuItem,并且将Text作为MessageDialog的内容输出:

<StackPanel>
<TextBox x:Name="TextElement"/>
<local:MenuItem Command="{Binding}" CommandParameter="{Binding ElementName=TextElement,Path=Text}"/>
</StackPanel>
public MenuItemSamplePage()
{
this.InitializeComponent();
var command = new DelegateCommand<object>(Click, CanExecute);
this.DataContext = command;
} private void Click(object parameter)
{
MessageDialog dialog = new MessageDialog(parameter.ToString());
dialog.ShowAsync();
} private bool CanExecute(object parameter)
{
string text = parameter as string;
return string.IsNullOrWhiteSpace(text) == false;
}

这里用到的DelegateCommand也是UWPCommunityToolkit中的类 :DelegateCommand

[UWP]了解模板化控件(7):支持Command的更多相关文章

  1. [UWP 自定义控件]了解模板化控件(7):支持Command

    以我的经验来说,要让TemplatedControl支持Command的需求不会很多,大部分情况用附加属性解决这个需求会更便利些,譬如UWPCommunityToolkit的HyperlinkExte ...

  2. 【UWP】使用Action代替Command

    在Xaml中,说到绑定,我们用的最多的应该就是ICommand了,通过Command实现ViewModel到View之间的命令处理,例如Button默认就提供了Command支持,如下 Xaml: & ...

  3. [UWP]了解模板化控件(8):ItemsControl

    1. 模仿ItemsControl 顾名思义,ItemsControl是展示一组数据的控件,它是UWP UI系统中最重要的控件之一,和展示单一数据的ContentControl构成了UWP UI的绝大 ...

  4. Win10商店东方财富网 UWP版更新,支持平板,PC,手机

    东方财富股份有限公司 近日向Win10商店提交了东方财富网V4.1版,这次为广大Win10平台用户带来了期待已久的桌面版本,可谓是良心厂商,值得鼓励和支持.4.1主要更新: 1. 支持桌面Window ...

  5. Win10 UWP 开发系列:支持异步的SQLite

    上篇文章已经实现了在UWP中使用SQLite作为本地存储,作为移动端的程序,及时响应用户的操作是提高用户体验的重要途径,因此UWP的很多api都是异步的.那么如何使SQLite支持异步呢? 参考SQL ...

  6. [UWP]了解模板化控件(1):基础知识

    1.概述 UWP允许开发者通过两种方式创建自定义的控件:UserControl和TemplatedControl(模板化控件).这个主题主要讲述如何创建和理解模板化控件,目标是能理解模板化控件常见的知 ...

  7. [UWP]了解模板化控件(2):模仿ContentControl

    ContentControl是最简单的TemplatedControl,而且它在UWP出场频率很高.ContentControl和Panel是VisualTree的基础,可以说几乎所有VisualTr ...

  8. [UWP]了解模板化控件(2.1):理解ContentControl

    UWP的UI主要由布局容器和内容控件(ContentControl)组成.布局容器是指Grid.StackPanel等继承自Panel,可以拥有多个子元素的类.与此相对,ContentControl则 ...

  9. [UWP]了解模板化控件(4):TemplatePart

    1. TemplatePart TemplatePart(部件)是指ControlTemplate中的命名元素.控件逻辑预期这些部分存在于ControlTemplate中,并且使用protected ...

随机推荐

  1. CentOS7.x系统根目录分区扩容

    说明:系统版本为 Linux version 3.10.0-327.el7.x86_64 step1. 查看现有磁盘信息,可以看出根分区有45G [root@DEV-CMDB-DB02 ~]# df ...

  2. Vue.js简单的应用

    1:一个简单实现 下面代码部分: <body> <div id="myDiv1"> {{userName}} </div> </body& ...

  3. sockt初级了解 感悟 一起打怪升级偶

    刚接触来谈谈对sockt基础的一点理解,多线性下次再发.也逛了逛博客,有一篇基础讲的停息在这推荐下sockt套接字编程全绍辉 首先贴下代码#服务器 import socket skt=socket.s ...

  4. 《HelloGitHub》第 20 期

    前言 HelloGitHub 项目已经累积到 3k+ Stars.本项能够走到今天,帮助到越来越多的人.少不了热爱开源.不断为本项目贡献项目的小伙伴们. 贡献者列表 很多人都有想法,付诸于行动在少数, ...

  5. head first python菜鸟学习笔记(第三章)

    1.os.chdir()切换到指定目录下,os.getcwd(),得到当前目录. >>> import os>>> os.chdir('D:\\CodeDocume ...

  6. 简单模板view调用

    $this->display();//模板名称与当前控制器.当前操作方法的名称不一致 $this->display();//调用当前控制器对应目录指定名称的模板 $this->dis ...

  7. js中一些注意点 ps不断更新中....

    nextSibling 和 nextElementSibling 的区别 (previousSibling 和 previousElementSibling ) nextSibling 在IE8及以下 ...

  8. CCF-201403-2-窗口

    问题描述 试题编号: 201403-2 试题名称: 窗口 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 在某图形操作系统中,有 N 个窗口,每个窗口都是一个两边与坐标轴分别平 ...

  9. spring mvc 复杂参数注入

    过了这么久,又重新把博客拾起来了 来上海工作也已经有将近两周的时间了, 今天在整理项目的时候,遇到了一个关于参数注入的问题 背景: 我的开发前台用的是extjs4,在对后台spring mvc提交表单 ...

  10. 在外围获取APP的机密信息

    叶孤城原创,转载须授权. 小白:偷窥狂,不,叶城主,怎么还不发起攻击,还在外围搞什么? 叶孤城:闭嘴,能外围解决的问题就不要破解,你以为你会天外飞仙啊! 小白:-- 本文解决一个问题:通过抓包分析出重 ...