2

I have WPF xaml code like below:

  <StackPanel  FocusManager.FocusedElement="{Binding FocusedElement}">
    <TextBox Name="txtbox1" Text="FirstText"/>
    <TextBox Name="txtbox3" Text="SecondText"/>
    <TextBox Name="txtbox2" Text="ThirdText"/>
  </StackPanel>

How can I Bind FocusedElement to Property in ViewModel? similar code below:

Switch(Type)
{
Case "FirstType" :
  FocusedElement = "txtbox1";
break;
Case "SecondType" :
   FocusedElement = "txtbox2";
break;
Case "ThiredType" :
   FocusedElement = "txtbox3";
break;
}
oliver
  • 362
  • 2
  • 5
  • 13

2 Answers2

6

The viewmodel should never know about the view, and quite certainly not know some UIElement names. But given that the viewmodel really needs to be able to manage focus (I suggest you make sure that really is the case before proceeding), you could do something like this:

enter image description here

ViewModel:

public enum Focuses
{
    None = 0,
    First,
    Second,
    Third
}

public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    private Focuses _focusedElement;
    public Focuses FocusedElement { get { return _focusedElement; } set { _focusedElement = value; OnPropertyChanged("FocusedElement"); } }


    public ViewModel()
    {
        this.FocusedElement = Focuses.Second;
    }
}

Xaml:

<StackPanel >
    <TextBox Name="txtbox1" Text="FirstText"/>
    <TextBox Name="txtbox2" Text="SecondText"/>
    <TextBox Name="txtbox3" Text="ThirdText"/>
    <StackPanel.Style>
        <!-- cannot use DataTriggers directly in StackPanel.Triggers, therefore Style -->
        <Style TargetType="{x:Type StackPanel}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding FocusedElement}" Value="First">
                    <Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=txtbox1}"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding FocusedElement}" Value="Second">
                    <Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=txtbox2}"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding FocusedElement}" Value="Third">
                    <Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=txtbox3}"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </StackPanel.Style>
</StackPanel>
Mike Fuchs
  • 12,081
  • 6
  • 58
  • 71
0

The FocusedElement is the element which has logical focus for a specific focus scope.

The logical focus and not the "real focus" such as txtBox1.Focus();

Logical focus can be set multiple times while only one element can have keyboard focus.

Do you really need the logical focus?

You can listen to GotFocus event and then do some custom logic as example.

snowy hedgehog
  • 652
  • 1
  • 7
  • 23