zoukankan      html  css  js  c++  java
  • Silverlight MVVM设置控件焦点

         silverlight开发中设置某个控件的焦点,如果是在code behind 情况下可以通过直接设定某个控件的focus()方法就可以实现。但是如果我们是用MVVM模式下通过绑定来实现呢?比如这样一个场景,一个登陆页面,需要设定登录名控件TboxLogin(TextBox)默认具有焦点。通过研究发现,TextBox并没有设置Focus的依赖属性,因此,直接绑定是不能实现的,我们只能通过其他方法来实现。

       在Silverlight中有个System.Windows.Interactivity.dll的类库,专门用来处理Silverlight交互方面的功能,我们可以通过其中的Behavior来实现这里的需求。比如定义一个TextBoxFocusBehavior的类,让它继承自Behavior<TextBox>并在其中定义一个附加属性IsFocused,然后通过该属性的变化来设定TextBox 是否有焦点。  

    TextBoxFocusBehavior
     1  public class TextBoxFocusBehavior : Behavior<TextBox>
     2     { 
     3         public static bool GetIsFocused(DependencyObject obj)
     4         {
     5             return (bool)obj.GetValue(IsFocusedProperty);
     6         }
     7 
     8         public static void SetIsFocused(DependencyObject obj, bool value)
     9         {
    10             obj.SetValue(IsFocusedProperty, value);
    11         } 
    12         public static readonly DependencyProperty IsFocusedProperty =
    13             DependencyProperty.RegisterAttached("IsFocused", typeof(bool),
    14             typeof(TextBoxFocusBehavior), new PropertyMetadata((s, e) =>
    15             {
    16                 var textBox = s as TextBox;
    17                 if (textBox != null && e.NewValue is bool && (bool)e.NewValue)
    18                 {
    19                     textBox.Focus();
    20                 }
    21             }));
    22     }

    定义好上面的类后,就可以在Xaml中通过绑定ViewModel中的某个bool属性到TextBox的IsFocused附加属性了,Xaml中处理类似: <TextBox Text="{Binding LoginName, Mode=TwoWay, UpdateSourceTrigger= PropertyChanged}"
                     loc:TextBoxFocusBehavior.IsFocused="{Binding IsFocused, Mode=TwoWay}" >
            </TextBox> 这样只要ViewModel中的IsFocused应属性变化了,就可以通知TextBox是否具有焦点。

    延伸:这里我们处理的是TextBox的焦点设置,有可能我们之后还要设定PasswordBox或者RichTextbox等其他控件的焦点。因此,这里我们可以对这个Behavior进行抽象处理,这样具体某个类型的控件需要设定焦点行为时候,直接继承该抽象类就行了。实现如下:

    ControlFocusBehavior
     1  public class ControlFocusBehavior<T> : Behavior<FrameworkElement> where T : Control
     2     {
     3         public static bool GetIsFocused(T obj)
     4         {
     5             return (bool)obj.GetValue(IsFocusedProperty);
     6         }
     7 
     8         public static void SetIsFocused(T obj, bool value)
     9         {
    10             obj.SetValue(IsFocusedProperty, value);
    11         }
    12 
    13         public static readonly DependencyProperty IsFocusedProperty =
    14             DependencyProperty.RegisterAttached("IsFocused", typeof(bool),
    15             typeof(ControlFocusBehavior<T>), new PropertyMetadata((obj, e) =>
    16             {
    17                 var element = obj as T;
    18                 if (element != null && e.NewValue is bool && (bool)e.NewValue)
    19                 {
    20                     element.Focus();
    21                 }
    22             }));
    23     }

    有了上面的抽象类,这个时候我们就好办了,比如上面的TextBox需要焦点处理。直接通过该抽象类,实现一个TextBox的就行 

     public class TextBoxFocusBehavior : ControlFocusBehavior<TextBox>    {}

    PasswordBox同样的: public class PasswordBoxFocusBehavior : ControlFocusBehavior<TextBox>    {}

    这样就达到了我们的目的了。

    备注:在Silverlight程序启动后,我们的第一个Xaml其实并没有获取到焦点,需要在启动的第一个Xaml页面中设定一行代码,让它默认得到焦点 HtmlPage.Plugin.Focus();

    如果您觉得本文对您有所帮助,请点一下"推荐"按钮,您的"推荐"将是我最大的写作动力!
    作者:rpoplar
    出处:http://www.cnblogs.com/rpoplar/
    本文版权归作者【rpoplar】和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究其法律责任的权利。
  • 相关阅读:
    什么是ORM
    ORM优缺点
    Azure 中快速搭建 FTPS 服务
    连接到 Azure 上的 SQL Server 虚拟机(经典部署)
    在 Azure 虚拟机中配置 Always On 可用性组(经典)
    SQL Server 2014 虚拟机的自动备份 (Resource Manager)
    Azure 虚拟机上的 SQL Server 常见问题
    排查在 Azure 中新建 Windows 虚拟机时遇到的经典部署问题
    上传通用化 VHD 并使用它在 Azure 中创建新 VM
    排查在 Azure 中新建 Windows VM 时遇到的部署问题
  • 原文地址:https://www.cnblogs.com/rpoplar/p/2838301.html
Copyright © 2011-2022 走看看