[UWP]了解模板化控件(7):支持Command
以我的经验来说,要让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的更多相关文章
- [UWP 自定义控件]了解模板化控件(7):支持Command
以我的经验来说,要让TemplatedControl支持Command的需求不会很多,大部分情况用附加属性解决这个需求会更便利些,譬如UWPCommunityToolkit的HyperlinkExte ...
- 【UWP】使用Action代替Command
在Xaml中,说到绑定,我们用的最多的应该就是ICommand了,通过Command实现ViewModel到View之间的命令处理,例如Button默认就提供了Command支持,如下 Xaml: & ...
- [UWP]了解模板化控件(8):ItemsControl
1. 模仿ItemsControl 顾名思义,ItemsControl是展示一组数据的控件,它是UWP UI系统中最重要的控件之一,和展示单一数据的ContentControl构成了UWP UI的绝大 ...
- Win10商店东方财富网 UWP版更新,支持平板,PC,手机
东方财富股份有限公司 近日向Win10商店提交了东方财富网V4.1版,这次为广大Win10平台用户带来了期待已久的桌面版本,可谓是良心厂商,值得鼓励和支持.4.1主要更新: 1. 支持桌面Window ...
- Win10 UWP 开发系列:支持异步的SQLite
上篇文章已经实现了在UWP中使用SQLite作为本地存储,作为移动端的程序,及时响应用户的操作是提高用户体验的重要途径,因此UWP的很多api都是异步的.那么如何使SQLite支持异步呢? 参考SQL ...
- [UWP]了解模板化控件(1):基础知识
1.概述 UWP允许开发者通过两种方式创建自定义的控件:UserControl和TemplatedControl(模板化控件).这个主题主要讲述如何创建和理解模板化控件,目标是能理解模板化控件常见的知 ...
- [UWP]了解模板化控件(2):模仿ContentControl
ContentControl是最简单的TemplatedControl,而且它在UWP出场频率很高.ContentControl和Panel是VisualTree的基础,可以说几乎所有VisualTr ...
- [UWP]了解模板化控件(2.1):理解ContentControl
UWP的UI主要由布局容器和内容控件(ContentControl)组成.布局容器是指Grid.StackPanel等继承自Panel,可以拥有多个子元素的类.与此相对,ContentControl则 ...
- [UWP]了解模板化控件(4):TemplatePart
1. TemplatePart TemplatePart(部件)是指ControlTemplate中的命名元素.控件逻辑预期这些部分存在于ControlTemplate中,并且使用protected ...
随机推荐
- 走进Spark生态圈:环境的安装与配置
什么是Spark? Apache Spark 是一种大规模数据处理的快速通用引擎,使用基于内存的处理方式,较与MapReduce而言,解决了其shuffle多次IO操作带来的效率低问题,从而达到快速的 ...
- ecshop添加菜单以及权限分配
增加菜单并添加权限: admin/includes/inc_menu.php 添加 $modules['**_name1']['name2'] = 'your href' admin/includes ...
- javaweb-1-B/S初论
一.B/S结构的基本概念 1.什么是动态网页 2.为什么需要动态网页 3.如何实现动态网页 4.为什么学习B/S技术 4.1C/S结构 优点: 1.C/S架构的界面和操作可以很丰富. 2.安全性能可以 ...
- mysql 查询各数据库的占用大小
select TABLE_SCHEMA, concat(truncate(sum(data_length)/1024/1024,2),' MB') as data_size, concat(trunc ...
- Android WebView 上传各种文件(包括拍照 录像 录音 文件 音乐 等,用到图片或拍照的,可以参考下)
我也是从网上扒下来的,经过多次实验,找到了个好用的.网上能搜到最多的也就是这个解决方案,我英文不好,也没仔细研究,但大多数都是出自这: http://stackoverflow.com/questio ...
- JAVA基础面试(一)
1.一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 可以有多个类,但只能有一个public的类,并且public的类名必须与文件名相一致. 2.Java有 ...
- 【Java入门提高篇】Day3 抽象类与接口的比较
抽象类跟接口都讲完了,现在来做一个比较. 其实说实话,没有多大的可比较性,它们是完全不同的两个东西,它们的抽象不在同一个层级上.但是为了让大家更好的理解,还是做一个比较吧,毕竟它们都很抽象(233). ...
- org.hibernate.validator.constraints.NotBlank' validating type 'java.lang.Integer
使用hibernate时,在save方法时,报了:org.hibernate.validator.constraints.NotBlank' validating type 'java.lang.In ...
- 八、Hadoop学习笔记————调优之Hive调优
表1表2的join和表3表4的join同时运行 此法需要关注是否有数据倾斜(大量数据集中在某一区间段)
- python中使用selenium调用Firefox缺少geckodriver解决方法
from selenium import webdriver driver=webdriver.Firefox() 会报错 解决方法: 因为缺少geckodriver.exe,先到https://gi ...