Dienstag, 13. September 2011

MVVM TextBox Focus



If your are an MVVM enthusiast like me, you may will encounter the following problem: You want to focus a specific textbox from your ViewModel, but you do not have access to your TextBox. So you need some property you can bind to:

   1:  public static class FocusExtension
   2:  {
   3:      public static bool GetIsFocused(DependencyObject obj)
   4:      {
   5:          return (bool)obj.GetValue(IsFocusedProperty);
   6:      }
   7:   
   8:   
   9:      public static void SetIsFocused(DependencyObject obj, bool value)
  10:      {
  11:          obj.SetValue(IsFocusedProperty, value);
  12:      }
  13:   
  14:   
  15:      public static readonly DependencyProperty IsFocusedProperty =
  16:              DependencyProperty.RegisterAttached(
  17:                  "IsFocused", typeof(bool), typeof(FocusExtension),
  18:                  new UIPropertyMetadata(false, OnIsFocusedPropertyChanged));
  19:   
  20:   
  21:      private static void OnIsFocusedPropertyChanged(DependencyObject d,
  22:              DependencyPropertyChangedEventArgs e)
  23:      {
  24:          var uie = (UIElement)d;
  25:          if ((bool)e.NewValue)
  26:          {
  27:              uie.Focus();
  28:          }
  29:      }
  30:  }

There is only one drawback in this solution: If another control gets the focus, the IsTextBoxFocused Property does not change. So if you try to focus the textbox if the property (still) is true, you have to set it to false and fire the PropertyChanged notification before setting it to true.


   1:  private bool _isFocused = false;
   2:  public bool IsTextBoxFocused
   3:  {
   4:      get
   5:      {
   6:          return _isFocused;
   7:      }
   8:      set
   9:      {
  10:          if (_isFocused == value)
  11:          {
  12:              _isFocused = false;
  13:              RaisePropChanged("IsTextBoxFocused");
  14:          }
  15:          _isFocused = value;
  16:          RaisePropChanged("IsTextBoxFocused");
  17:      }
  18:  } 

 
 
<TextBox local:FocusExtension.IsFocused="{Binding IsTextBoxFocused}" /> 
 
 

If you simply want to set the initial focus to a specific TextBox (or any other control), you can use the FocusManager.FocusedElement property of  any superior layout panel (which contains the TextBox that should be focused)

<Grid x:Name="LayoutRoot" 
      FocusManager.FocusedElement="{Binding 
                       ElementName=myInitialFocusedTextBox}">
    ...
    <TextBox Name="myInitialFocusedTextBox"  />
    ...
</Grid>

1 Kommentar:

  1. Considerable article, We at Addhunters shifted this service to a level much higher than the broker concept. you can see more details like this article alrayyan

    AntwortenLöschen