本篇文章主要介绍了"uwp [UWP]了解模板化控件7:支持Command",主要涉及到uwp方面的内容,对于Windows Phone开发感兴趣的同学可以参考一下:
以我的经验来说,要让TemplatedControl支持Command的需求不会很多,大部分情况用附加属性解决这个需求会更便利些,譬如UWPCommunityT...
以我的经验来说,要让TemplatedControl支持Command的需求不会很多,大部分情况用附加属性解决这个需求会更便利些,譬如UWPCommunityToolkit的HyperlinkExtensions。
如果正在从头设计自定义控件并真的需要提供命令支持,可以参考这篇文章。支持Command的步骤比较简单,所以这篇文章比较简短。
要实现Command支持,控件中要执行如下步骤:
- 定义Command和CommandParameter属性。
- 监视Command的CanExecuteChanged事件。
- 在CanExecuteChanged的事件处理函数及CommandParameter的PropertyChangedCallback中,根据Command.CanExecute(CommandParameter)的结果设置控件的IsEnabled属性。
- 在某个事件(Click或者ValueChanged)中执行Command。
MenuItem是实现了Command支持的示例,重载了OnPointerPressed并且在其中执行Command:
publicclass MenuItem : Control
{
/// /// 标识 Command 依赖属性。/// publicstaticreadonly DependencyProperty CommandProperty =
DependencyProperty.Register("Command", typeof(ICommand), typeof(MenuItem), newPropertyMetadata(null, OnCommandChanged));
privatestaticvoidOnCommandChanged(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);
}
/// /// 标识 CommandParameter 依赖属性。/// publicstaticreadonly DependencyProperty CommandParameterProperty =
DependencyProperty.Register("CommandParameter", typeof(object), typeof(MenuItem), newPropertyMetadata(null, OnCommandParameterChanged));
privatestaticvoidOnCommandParameterChanged(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);
}
publicMenuItem()
{
this.DefaultStyleKey = typeof(MenuItem);
}
publicevent RoutedEventHandler Click;
/// /// 获取或设置Command的值/// public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
/// /// 获取或设置CommandParameter的值/// publicobject CommandParameter
{
get { return (object)GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
}
protectedvirtualvoidOnCommandParameterChanged(object oldValue, object newValue)
{
UpdateIsEnabled();
}
protectedvirtualvoidOnCommandChanged(ICommand oldValue, ICommand newValue)
{
if (oldValue != null)
oldValue.CanExecuteChanged -= OnCanExecuteChanged;
if (newValue != null)
newValue.CanExecuteChanged += OnCanExecuteChanged;
UpdateIsEnabled();
}
protectedvirtualvoidUpdateVisualState(bool useTransitions)
{
if (IsEnabled)
{
VisualStateManager.GoToState(this, "Normal", useTransitions);
}
else
{
VisualStateManager.GoToState(this, "Disabled", useTransitions);
}
}
protectedoverridevoidOnPointerPressed(PointerRoutedEventArgs e)
{
base.OnPointerPressed(e);
Click?.Invoke(this, newRoutedEventArgs());
if ((null != Command) && Command.CanExecute(CommandParameter))
{
Command.Execute(CommandParameter);
}
}
privatevoidOnCanExecuteChanged(object sender, EventArgs e)
{
UpdateIsEnabled();
}
privatevoidUpdateIsEnabled()
{
IsEnabled = (null == Command) || Command.CanExecute(CommandParameter);
UpdateVisualState(true);
}
}
以下是使用示例,作用是当TextBox的Text不为空时可以点击MenuItem,并且将Text作为MessageDialog的内容输出: