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();

 

 

你可能感兴趣的:(silverlight)