65.9K
CodeProject 正在变化。 阅读更多。
Home

UWP TextBox 行为, 用于焦点和命令绑定

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2016年3月24日

CPOL

2分钟阅读

viewsIcon

23534

downloadIcon

309

通过附加属性,为通用 Windows 平台 TextBox 添加 MVVM 焦点控制和按键按下时命令执行功能。

引言

这是一个行为类,您可以将其插入到您的通用 Windows 平台中,以提供以 MVVM 方式控制 TextBox 焦点的方式,并提供基于按键按下执行命令的能力。

背景

请参阅以下文章,了解附加行为的概念介绍:

Using the Code

behaviour 类提供两个功能。

焦点

焦点控制功能包含以下元素。

首先,一个附加属性,用于指示控件是否具有焦点。

 /// <summary>
 /// Declare new attached property.
 /// </summary>
 public static readonly DependencyProperty IsFocusedProperty =
       DependencyProperty.RegisterAttached("IsFocused", typeof(bool),
       typeof(TextBoxBehaviour), new PropertyMetadata(default(bool), OnIsFocusedChanged));

IsFocused 属性发生更改时,将调用 OnIsFocusedChanged 方法。 在该方法中,如果 IsFocused 属性为 true,则控件将获得 Focused 状态。 此外,还为 LostFocus 事件附加了处理程序。

        /// <summary>
        /// This method will be called when the IsFocused
        /// property is changed
        /// </summary>
        /// <param name="s">System.Object repersenting the source of the event.</param>
        /// <param name="e">The arguments for the event.</param>
        public static void OnIsFocusedChanged(DependencyObject s, DependencyPropertyChangedEventArgs e)
        {
            //If the host object is a frame.
            if (s is TextBox)
            {
                //Unbox.
                TextBox t = s as TextBox;

                //If setting is true.
                if ((bool)e.NewValue)
                {
                    //Set the Focus
                    t.Focus(FocusState.Pointer);

                    //Attach handling for lost focus.
                    t.LostFocus += textbox_LostFocus;
                }
                else
                {
                    //Remove handling.
                    t.LostFocus -= textbox_LostFocus;
                }
            }
        }

LostFocus 事件处理程序中,属性将被重置。

        /// <summary>
        /// Handling for when the texbox looses focus.
        /// </summary>
        /// <param name="sender">System.Object repersenting the source of the event.</param>
        /// <param name="e">The arguments for the event.</param>
        private static void textbox_LostFocus(object sender, RoutedEventArgs e)
        {
            //Unbox.
            TextBox t = sender as TextBox;

            //Set dependency property.
            t.SetValue(IsFocusedProperty, false);
        }

在您的视图中,添加行为的命名空间。

xmlns:behave="using:UtilitiesUniversal.Behaviours"

然后,您可以像以下示例一样使用该附加属性。 请注意,我已将该属性绑定到页面其他位置的切换按钮元素的选中状态。 现在,控件的焦点将与切换按钮的选中状态同步切换。 这对于移动设备上的单手操作来说是一个潜在的有用功能。

<TextBox Name="filterText" 
behave:TextBoxBehaviour.IsFocused="{Binding ElementName=filterBtn, 
Path=IsChecked, Mode=TwoWay}" Height="48"   
InputScope="AlphanumericFullWidth" 
VerticalContentAlignment="Center" FontSize="25" >

...

 <CommandBar ClosedDisplayMode="Compact" Name="commands">
                <AppBarToggleButton Icon="Filter" 
                x:Uid="Filter" Name="filterBtn" IsChecked="False"/>
  </CommandBar>       

命令绑定

行为类提供的另一个功能是在按键按下时执行命令。

命令绑定功能包含以下元素。

首先,有一个属性用于存储所需的命令。

public static readonly DependencyProperty CommandProperty =
            DependencyProperty.RegisterAttached("Command", typeof(ICommand),
                typeof(TextBoxBehaviour), new PropertyMetadata(null));     

另一个属性当然是触发命令所需的按键。

        public static readonly DependencyProperty CommandKeyProperty =
            DependencyProperty.RegisterAttached("CommandKey", typeof(string),
            typeof(TextBoxBehaviour), new PropertyMetadata(default(string), OnCommandKeyChanged));

OnCommandKeyChanged 中,为 KeyDown 事件附加了回调处理程序。

 private static void OnCommandKeyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is TextBox)
            {
                //Unbox.
                TextBox t = d as TextBox;


                //If the key is set.
                if (e.NewValue != null && e.NewValue.ToString().Length > 0)
                {
                    t.KeyDown += T_KeyDown;
                }
                else
                {
                    t.KeyDown -= T_KeyDown;
                }
            }
        }

KeyDown 事件处理程序中,将按下的按键与 CommandKey 属性进行比较,如果匹配,则执行该命令。

 private static void T_KeyDown(object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e)
        {
            TextBox t = sender as TextBox;

            if (e.Key.ToString() == t.GetValue(CommandKeyProperty).ToString())
            {
                //Handle.
                e.Handled = true;

                // Get command
                ICommand command = GetCommand(t);

                // Execute command
                command.Execute(null);
            }
        }

在您的视图中,添加行为的命名空间。

xmlns:behave="using:UtilitiesUniversal.Behaviours"

现在,您可以像以下示例一样使用该属性; 在示例中,当在 textbox 中按下 Enter 键时,我将在当前的 datacontext 中执行 ReadCommand

<TextBox AcceptsReturn="False" 
behave:TextBoxBehaviour.Command="{Binding ReadCommand}" 
behave:TextBoxBehaviour.CommandKey="{Binding FakeBinding,FallbackValue=Enter}"  
InputScope="AlphanumericFullWidth" 
VerticalContentAlignment="Center" FontSize="25"/>

关注点

根据我的经验,通用 Windows 平台不允许直接设置附加属性,即您必须使用绑定。 因此,上述绑定语法。

历史

  • 1.0
© . All rights reserved.