tags:

views:

1929

answers:

5

I have a textbox and a button in my view.

Now I am checking a condition upon button click and if the condition turns out to be false, displaying the message to the user, and then I have to set the cursor to the text box control.

if (companyref == null)
{
Lipper.Nelson.AdminClient.Main.Views.ContactPanels.CompanyAssociation cs = new Lipper.Nelson.AdminClient.Main.Views.ContactPanels.CompanyAssociation(); 

MessageBox.Show("Company does not exist.", "Error", MessageBoxButton.OK,
                    MessageBoxImage.Exclamation);

    cs.txtCompanyID.Focusable = true;

    System.Windows.Input.Keyboard.Focus(cs.txtCompanyID);

}

The above code is in view model.

The CompanyAssociation is the view name.

But the cursor is not getting set in the textbox.

The xaml is as under

<igEditors:XamTextEditor KeyDown="xamTextEditorAllowOnlyNumeric_KeyDown" Name="txtCompanyID" ValueChanged="txtCompanyID_ValueChanged" Text="{Binding Company.CompanyId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="{Binding ActualWidth, ElementName=border}" Grid.Column="1" Grid.Row="0" VerticalAlignment="Top" Margin="0,5,0,0" HorizontalAlignment="Stretch" IsEnabled="{Binding Path=IsEditable}" />

<Button Template="{StaticResource buttonTemp1}" Command="{Binding ContactCommand}" CommandParameter="searchCompany" Content="Search" Width="80" Grid.Column="2" Grid.Row="0" VerticalAlignment="Top" Margin="0" HorizontalAlignment="Left" IsEnabled="{Binding Path=IsEditable}" />

Please help

+7  A: 

Hey Pewned!

Let me answer to your question in three parts.

  1. I'm wondering what is "cs.txtCompanyID" in your example? Is it a TextBox control? If yes, then you are on a wrong way. Generally speaking it's not a good idea to have any reference to UI in your ViewModel. You can ask "Why?" but this is another question to post on Stackoverflow :).

  2. The best way to track down issues with Focus is... debugging .Net source code. No kidding. It saved me a lot of time many times. To enable .net source code debugging refer to Shawn Bruke's blog.

  3. Finally, general approach that I use to set focus from ViewModel is Attached Properties. I wrote very simple attached property, which can be set on any UIElement. And it can be bound to ViewModel's property "IsFocused" for example. Here it is:

    public static class FocusExtension
    {
     public static bool GetIsFocused(DependencyObject obj)
    {
     return (bool)obj.GetValue(IsFocusedProperty);
    }
    
    
     public static void SetIsFocused(DependencyObject obj, bool value)
     {
      obj.SetValue(IsFocusedProperty, value);
     }
    
    
     public static readonly DependencyProperty IsFocusedProperty =
      DependencyProperty.RegisterAttached(
       "IsFocused", typeof(bool),  typeof(FocusExtension),
       new UIPropertyMetadata(false, OnIsFocusedPropertyChanged));
    
    
     private static void OnIsFocusedPropertyChanged(DependencyObject d,
      DependencyPropertyChangedEventArgs e)
     {
      var uie = (UIElement) d;
      if ((bool)e.NewValue)
      {
       uie.Focus(); // Don't care about false values.
      }
     }
    }
    

Now in your View (in XAML) you can bind this property to your ViewModel:

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

Hope this helps :). If it doesn't refer to the answer #2.

Cheers.

Anvaka
+1, attached properties are the way to go here !
Thomas Levesque
Cool idea. I need to set IsUserNameFocused to true, then false again to get this working, is this right?
Sam
Thank you Sam. It depends. Sometimes it's enough to set it to true only once.
Anvaka
A: 

Hey anvaka,

your focusextension class works great. Thank you for this.

Unfortunately the focus was not visible at my textbox (blinking cursor). Calling DoEvents() helped me out. http://nmarian.blogspot.com/2007/09/doevents-in-wpf.html

Maybe this also works for you, Pewned.

CU

Scott Olson
A: 

Hi Scott,

Where exactly I have to call DoEvents, so I can get the blinking cursor in the textbox?

+1  A: 
        System.Windows.Forms.Application.DoEvents();
        Keyboard.Focus(tbxLastName);
KitWest
A: 

The problem is that once the IsUserNameFocused is set to true, it will never be false. This solves it by handling the GotFocus and LostFocus for the FrameworkElement.

I was having trouble with the source code formatting so here is a link

Shawn