2013-03-12 11 views
6

Ich habe Raster mit mehreren Textboxen. Je nachdem, welche Aktionen der Benutzer ausführen soll, sollte der Fokus auf einen der Textfelder geändert werden. Meine aktuelle Lösung verwendet eine String-Eigenschaft im ViewModel und einen Datentrigger in XAML, um den Fokus zu ändern. Es funktioniert gut, aber es scheint ein eher umständlicher Weg, um dies zu erreichen, also habe ich mich gefragt, ob es klarer getan werden könnte?Fokus in WPF mit MVVM setzen

<Grid.Style> 
     <Style TargetType="Grid"> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding FocusedItem}" Value="number"> 
        <Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=number}"/> 
       </DataTrigger> 
       <DataTrigger Binding="{Binding FocusedItem}" Value="name"> 
        <Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=name}"/> 
       </DataTrigger> 
       <DataTrigger Binding="{Binding FocusedItem}" Value="id"> 
        <Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=id}"/> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </Grid.Style> 

Wenn Sie den Wert der Immobilie und den Namen des Elements sehen können, ist das gleiche, so würde Ich mag diese i einen einzigen Auslöser tun, anstatt pro Element einen Auslöser aufweist.

Vielleicht kann jemand mit einem saubereren Weg kommen?

Vielen Dank im Voraus

+0

Könnte ich Sie fragen, warum Sie den Fokus auf diese Weise setzen? Da der Benutzer auch Tab by TabIndex verwenden kann, müssen Sie nur einmal den Fokus setzen – WiiMaxx

+1

solange diese Lösung für Sie funktioniert, sollten Sie es nehmen – blindmeis

+2

Persönlich denke ich, Focus ist ein UI-spezifisches Konzept, so würde ich sagen All meine Fokusbehandlung im Code hinter der View und nicht in meinem ViewModel (es sei denn, der Fokus hatte eine bestimmte Bedeutung in der Geschäftslogik). – Rachel

Antwort

4

Die Art und Weise war ich Fokus in einem meiner Projekte behandelt Einstellung durch einen Fokus Erweiterung mit (ich entschuldige ich mich nicht erinnern, wo ich die Original-Beitrag sah dies aus ist).

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

Und dann in XAML-Datei Ich benutze es als Abhängigkeitseigenschaft:

<TextBox Uid="TB1" FontSize="13" localExtensions:FocusExtension.IsFocused="{Binding Path=TB1Focus}" Height="24" HorizontalAlignment="Left" Margin="113,56,0,0" Name="TB_UserName" VerticalAlignment="Top" Width="165" Text="{Binding Path=TB1Value, UpdateSourceTrigger=PropertyChanged}" /> 

Sie können dann eine Bindung verwenden, um den Fokus einzustellen.

+1

Danke. Ich habe darüber nachgedacht, eine Lösung wie diese zu verwenden, habe mich aber dagegen entschieden, da sie meine VM zu stark an die tatsächliche Benutzeroberfläche koppelt. Ich fange an zu denken, dass Code-Behind wahrscheinlich der richtige Weg ist. – Farawin

+0

Ihr Textfeld muss auch Focusable = "True" gesetzt haben, sonst funktioniert das nicht – krilovich

+1

Der ursprüngliche Beitrag, den ich glaube, ist http://stackoverflow.com/questions/1356045/set-focus-on-textbox-in- wpf-von-view-model-c-wpf –