it-swarm.com.de

Festlegen des Textfelds in WPF vom Ansichtsmodell (C #)

Ich habe eine TextBox und eine Button aus meiner Sicht.

Jetzt prüfe ich eine Bedingung beim Klicken auf die Schaltfläche. Wenn sich herausstellt, dass die Bedingung falsch ist, wird die Nachricht dem Benutzer angezeigt, und ich muss den Cursor auf das Steuerelement TextBox setzen.

if (companyref == null)
{
    var 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);
}

Der obige Code befindet sich im ViewModel.

CompanyAssociation ist der Ansichtsname.

Der Cursor wird jedoch nicht in TextBox gesetzt.

Das Xaml ist:

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

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

Lassen Sie mich Ihre Frage in drei Teilen beantworten. 

  1. Ich frage mich, was ist "cs.txtCompanyID" in Ihrem Beispiel? Ist es ein TextBox-Steuerelement? Wenn ja, dann bist du auf einem falschen Weg. Im Allgemeinen ist es nicht ratsam, in Ihrem ViewModel einen Verweis auf die Benutzeroberfläche zu haben. Sie können fragen "Warum?" Dies ist jedoch eine weitere Frage, die auf Stackoverflow zu posten ist :).

  2. Der beste Weg, um Probleme mit Focus aufzudecken, ist ... Debuggen von .NET-Quellcode. Im Ernst. Es hat mir viel Zeit gespart. Um das Debuggen von .NET-Quellcode zu aktivieren, beziehen Sie sich auf Shawn Brukes blog.

  3. Der allgemeine Ansatz, den ich zum Einstellen des Fokus von ViewModel verwende, ist Attached Properties. Ich habe eine sehr einfache angefügte Eigenschaft geschrieben, die für jedes UIElement festgelegt werden kann. Und es kann zum Beispiel an ViewModels Eigenschaft "IsFocused" gebunden werden. Hier ist es:

    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.
            }
        }
    }
    

    Jetzt können Sie in Ihrer Ansicht (in XAML) diese Eigenschaft an Ihr ViewModel binden:

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

Hoffe das hilft :). Wenn es sich nicht auf die Antwort Nr. 2 bezieht. 

Prost.

239
Anvaka

Ich weiß, dass diese Frage bereits tausend Mal beantwortet wurde, aber ich habe einige Änderungen an Anvakas Beitrag vorgenommen, von denen ich denke, dass sie anderen helfen werden, die ähnliche Probleme hatten wie ich.

Erstens habe ich das oben angefügte angebrachte Eigentum folgendermaßen geändert:

public static class FocusExtension
{
    public static readonly DependencyProperty IsFocusedProperty = 
        DependencyProperty.RegisterAttached("IsFocused", typeof(bool?), typeof(FocusExtension), new FrameworkPropertyMetadata(IsFocusedChanged){BindsTwoWayByDefault = true});

    public static bool? GetIsFocused(DependencyObject element)
    {
        if (element == null)
        {
            throw new ArgumentNullException("element");
        }

        return (bool?)element.GetValue(IsFocusedProperty);
    }

    public static void SetIsFocused(DependencyObject element, bool? value)
    {
        if (element == null)
        {
            throw new ArgumentNullException("element");
        }

        element.SetValue(IsFocusedProperty, value);
    }

    private static void IsFocusedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var fe = (FrameworkElement)d;

        if (e.OldValue == null)
        {
            fe.GotFocus += FrameworkElement_GotFocus;
            fe.LostFocus += FrameworkElement_LostFocus;
        }

        if (!fe.IsVisible)
        {
            fe.IsVisibleChanged += new DependencyPropertyChangedEventHandler(fe_IsVisibleChanged);
        }

        if ((bool)e.NewValue)
        {
            fe.Focus();
        }
    }

    private static void fe_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        var fe = (FrameworkElement)sender;
        if (fe.IsVisible && (bool)((FrameworkElement)sender).GetValue(IsFocusedProperty))
        {
            fe.IsVisibleChanged -= fe_IsVisibleChanged;
            fe.Focus();
        }
    }

    private static void FrameworkElement_GotFocus(object sender, RoutedEventArgs e)
    {
        ((FrameworkElement)sender).SetValue(IsFocusedProperty, true);
    }

    private static void FrameworkElement_LostFocus(object sender, RoutedEventArgs e)
    {
        ((FrameworkElement)sender).SetValue(IsFocusedProperty, false);
    }
}

Mein Grund für das Hinzufügen der Sichtbarkeitsreferenzen waren Registerkarten. Wenn Sie die angefügte Eigenschaft auf einer anderen Registerkarte außerhalb der anfangs sichtbaren Registerkarte verwendet haben, funktionierte die angefügte Eigenschaft offenbar nicht, bis Sie das Steuerelement manuell fokussierten.

Das andere Hindernis bestand darin, die zugrunde liegende Eigenschaft auf elegante Weise zurückzusetzen, wenn sie den Fokus verlor. Dort kamen die verlorenen Fokusereignisse ins Spiel.

<TextBox            
    Text="{Binding Description}"
    FocusExtension.IsFocused="{Binding IsFocused}"/>

Wenn es einen besseren Weg gibt, mit dem Sichtbarkeitsproblem umzugehen, lass es mich wissen.

Hinweis: Danke an Apfelkuacha für den Vorschlag, den BindsTwoWayByDefault in die DependencyProperty zu setzen. Ich hatte das schon vor langer Zeit in meinem eigenen Code getan, aber diesen Beitrag nie aktualisiert. Der Modus = TwoWay ist aufgrund dieser Änderung nicht mehr im WPF-Code erforderlich.

64
Zamotic

Ich denke, der beste Weg ist, das MVVM-Prinzip sauber zu halten.... Daher müssen Sie grundsätzlich die mit MVVM Light gelieferte Messenger-Klasse verwenden.

in Ihrem Viewmodel (exampleViewModel.cs) schreiben Sie folgendes 

 Messenger.Default.Send<string>("focus", "DoFocus");

schreibe jetzt in deine View.cs (nicht die XAML der view.xaml.cs) folgendes in den Konstruktor

 public MyView()
        {
            InitializeComponent();

            Messenger.Default.Register<string>(this, "DoFocus", doFocus);
        }
        public void doFocus(string msg)
        {
            if (msg == "focus")
                this.txtcode.Focus();
        }

diese Methode läuft gut und mit weniger Code und Einhaltung der MVVM-Standards

28
Adam

Keines davon funktionierte für mich genau, aber für andere habe ich am Ende auf der Grundlage des hier bereits bereitgestellten Codes geschrieben.

Die Nutzung wäre wie folgt:

<TextBox ... h:FocusBehavior.IsFocused="True"/>

Und die Implementierung wäre wie folgt:

/// <summary>
/// Behavior allowing to put focus on element from the view model in a MVVM implementation.
/// </summary>
public static class FocusBehavior
{
    #region Dependency Properties
    /// <summary>
    /// <c>IsFocused</c> dependency property.
    /// </summary>
    public static readonly DependencyProperty IsFocusedProperty =
        DependencyProperty.RegisterAttached("IsFocused", typeof(bool?),
            typeof(FocusBehavior), new FrameworkPropertyMetadata(IsFocusedChanged));
    /// <summary>
    /// Gets the <c>IsFocused</c> property value.
    /// </summary>
    /// <param name="element">The element.</param>
    /// <returns>Value of the <c>IsFocused</c> property or <c>null</c> if not set.</returns>
    public static bool? GetIsFocused(DependencyObject element)
    {
        if (element == null)
        {
            throw new ArgumentNullException("element");
        }
        return (bool?)element.GetValue(IsFocusedProperty);
    }
    /// <summary>
    /// Sets the <c>IsFocused</c> property value.
    /// </summary>
    /// <param name="element">The element.</param>
    /// <param name="value">The value.</param>
    public static void SetIsFocused(DependencyObject element, bool? value)
    {
        if (element == null)
        {
            throw new ArgumentNullException("element");
        }
        element.SetValue(IsFocusedProperty, value);
    }
    #endregion Dependency Properties

    #region Event Handlers
    /// <summary>
    /// Determines whether the value of the dependency property <c>IsFocused</c> has change.
    /// </summary>
    /// <param name="d">The dependency object.</param>
    /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
    private static void IsFocusedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        // Ensure it is a FrameworkElement instance.
        var fe = d as FrameworkElement;
        if (fe != null && e.OldValue == null && e.NewValue != null && (bool)e.NewValue)
        {
            // Attach to the Loaded event to set the focus there. If we do it here it will
            // be overridden by the view rendering the framework element.
            fe.Loaded += FrameworkElementLoaded;
        }
    }
    /// <summary>
    /// Sets the focus when the framework element is loaded and ready to receive input.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
    private static void FrameworkElementLoaded(object sender, RoutedEventArgs e)
    {
        // Ensure it is a FrameworkElement instance.
        var fe = sender as FrameworkElement;
        if (fe != null)
        {
            // Remove the event handler registration.
            fe.Loaded -= FrameworkElementLoaded;
            // Set the focus to the given framework element.
            fe.Focus();
            // Determine if it is a text box like element.
            var tb = fe as TextBoxBase;
            if (tb != null)
            {
                // Select all text to be ready for replacement.
                tb.SelectAll();
            }
        }
    }
    #endregion Event Handlers
}
17
Leo Vildosola

Dies ist ein alter Thread, aber es scheint keine Antwort mit Code zu geben, der die Probleme mit der akzeptierten Antwort von Anavanka anspricht: Es funktioniert nicht, wenn Sie die Eigenschaft im Viewmodel auf false oder Ihre Eigenschaft auf setzen true, klickt der Benutzer manuell auf etwas anderes und setzt es erneut auf true. Ich konnte auch die Lösung von Zamotic nicht dazu bringen, zuverlässig zu arbeiten.

Wenn ich einige der obigen Diskussionen zusammenbringe, bekomme ich den folgenden Code, der diese Probleme anspricht, denke ich:

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, null, OnCoerceValue));

    private static object OnCoerceValue(DependencyObject d, object baseValue)
    {
        if ((bool)baseValue)
            ((UIElement)d).Focus();
        else if (((UIElement) d).IsFocused)
            Keyboard.ClearFocus();
        return ((bool)baseValue);
    }
}

Trotzdem ist dies immer noch komplex für etwas, das in einer Zeile in codebehind gemacht werden kann, und CoerceValue ist nicht wirklich dazu gedacht, auf diese Art und Weise verwendet zu werden.

11
Rich N

In meinem Fall funktionierte die FocusExtension nicht, bis ich die Methode OnIsFocusedPropertyChanged ändere. Die ursprüngliche funktionierte nur im Debugging, wenn ein Haltepunkt den Prozess stoppte. Zur Laufzeit ist der Prozess zu schnell und es ist nichts passiert. Mit dieser kleinen Modifikation und der Hilfe unseres Freundes Task funktioniert dies in beiden Szenarien gut.

private static void OnIsFocusedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
  var uie = (UIElement)d;
  if ((bool)e.NewValue)
  {
    var action = new Action(() => uie.Dispatcher.BeginInvoke((Action)(() => uie.Focus())));
    Task.Factory.StartNew(action);
  }
}
4
Vincent Rithner

Anvakas brillanter Code ist für Windows Desktop-Anwendungen. Wenn Sie wie ich sind und die gleiche Lösung für Windows Store-Apps benötigen, könnte dieser Code nützlich sein:

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 PropertyMetadata(false, OnIsFocusedPropertyChanged));


    private static void OnIsFocusedPropertyChanged(DependencyObject d,
        DependencyPropertyChangedEventArgs e)
    {
        if ((bool)e.NewValue)
        {
            var uie = d as Windows.UI.Xaml.Controls.Control;

            if( uie != null )
            {
                uie.Focus(FocusState.Programmatic);
            }
        }
    }
}
3
PEK

Das Problem ist, dass, wenn IsUserNameFocused auf true festgelegt ist, es niemals false ist. Dies löst es, indem GotFocus und LostFocus für das FrameworkElement verarbeitet werden.

Ich hatte Probleme mit der Quellcode-Formatierung. Hier ist ein Link

2
Shawn

Ich benutze WPF/Caliburn Micro und habe festgestellt, dass "dfaivre" hier eine allgemeine und praktikable Lösung gefunden hat: http://caliburnmicro.codeplex.com/discussions/222892

1
kpp

Ich habe eine Lösung gefunden, indem ich den Code wie folgt editiere. Es ist nicht erforderlich, die Binding-Eigenschaft zuerst auf False und dann auf True zu setzen.

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)
    {
        if (d != null && d is Control)
        {
            var _Control = d as Control;
            if ((bool)e.NewValue)
            {
                // To set false value to get focus on control. if we don't set value to False then we have to set all binding
                //property to first False then True to set focus on control.
                OnLostFocus(_Control, null);
                _Control.Focus(); // Don't care about false values.
            }
        }
    }

    private static void OnLostFocus(object sender, RoutedEventArgs e)
    {
        if (sender != null && sender is Control)
        {
            (sender as Control).SetValue(IsFocusedProperty, false);
        }
    }
}
1

Für diejenigen, die Anvakas Lösung verwenden wollten, hatte ich Probleme mit der Bindung, die nur beim ersten Mal funktionierte, da lostfocus die Eigenschaft nicht auf false aktualisieren würde. Sie können die Eigenschaft jedes Mal manuell auf "false" und dann auf "true" setzen. Eine bessere Lösung wäre es, wenn Sie in Ihrer Eigenschaft Folgendes tun:

bool _isFocused = false;
    public bool IsFocused 
    {
        get { return _isFocused ; }
        set
        {
            _isFocused = false;
            _isFocused = value;
            base.OnPropertyChanged("IsFocused ");
        }
    }

Auf diese Weise müssen Sie es immer nur auf true setzen, und es wird der Fokus erhalten.

1
Tyrsius

Mach einfach das:

<Window x:class...
   ...
   ...
   FocusManager.FocusedElement="{Binding ElementName=myTextBox}"
>
<Grid>
<TextBox Name="myTextBox"/>
...
0
Zoltan

Niemand scheint den letzten Schritt aufgenommen zu haben, um die Aktualisierung von Attributen über gebundene Variablen zu erleichtern. Hier ist was ich mir ausgedacht habe. Lassen Sie mich wissen, ob es einen besseren Weg gibt, dies zu tun.

XAML

    <TextBox x:Name="txtLabel"
      Text="{Binding Label}"
      local:FocusExtension.IsFocused="{Binding txtLabel_IsFocused, Mode=TwoWay}" 
     />

    <Button x:Name="butEdit" Content="Edit"
        Height="40"  
        IsEnabled="{Binding butEdit_IsEnabled}"                        
        Command="{Binding cmdCapsuleEdit.Command}"                            
     />   

ViewModel

    public class LoginModel : ViewModelBase
    {

    public string txtLabel_IsFocused { get; set; }                 
    public string butEdit_IsEnabled { get; set; }                


    public void SetProperty(string PropertyName, string value)
    {
        System.Reflection.PropertyInfo propertyInfo = this.GetType().GetProperty(PropertyName);
        propertyInfo.SetValue(this, Convert.ChangeType(value, propertyInfo.PropertyType), null);
        OnPropertyChanged(PropertyName);
    }                


    private void Example_function(){

        SetProperty("butEdit_IsEnabled", "False");
        SetProperty("txtLabel_IsFocused", "True");        
    }

    }
0
Hugh

Nach der Implementierung der akzeptierten Antwort bin ich auf ein Problem gestoßen, dass beim Navigieren von Ansichten mit Prism die TextBox immer noch nicht den Fokus erhält. Eine geringfügige Änderung am PropertyChanged-Handler wurde behoben

    private static void OnIsFocusedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var uie = (UIElement)d;
        if ((bool)e.NewValue)
        {
            uie.Dispatcher.BeginInvoke(DispatcherPriority.Input, new Action(() =>
            {
                uie.Focus();
            }));
        }
    }
0
Joe H

Zunächst möchte ich Avanka dafür danken, dass sie mir bei der Lösung meines Fokusproblems geholfen hat. Es gibt jedoch einen Fehler in dem von ihm geposteten Code, und zwar in der Zeile: if (e.OldValue == null)

Das Problem, das ich hatte, war, dass e.oldValue nicht mehr null ist, wenn Sie zuerst in Ihre Ansicht klicken und das Steuerelement fokussieren. Wenn Sie dann die Variable so einstellen, dass das Steuerelement zum ersten Mal fokussiert wird, führt dies dazu, dass die Handler lostfocus und gotfocus nicht festgelegt werden .. Meine Lösung hierfür war wie folgt:

public static class ExtensionFocus
    {
    static ExtensionFocus()
        {
        BoundElements = new List<string>();
        }

    public static readonly DependencyProperty IsFocusedProperty =
        DependencyProperty.RegisterAttached("IsFocused", typeof(bool?),
        typeof(ExtensionFocus), new FrameworkPropertyMetadata(false, IsFocusedChanged));

    private static List<string> BoundElements;

    public static bool? GetIsFocused(DependencyObject element)
        {
        if (element == null)
            {
            throw new ArgumentNullException("ExtensionFocus GetIsFocused called with null element");
            }
        return (bool?)element.GetValue(IsFocusedProperty);
        }

    public static void SetIsFocused(DependencyObject element, bool? value)
        {
        if (element == null)
            {
            throw new ArgumentNullException("ExtensionFocus SetIsFocused called with null element");
            }
        element.SetValue(IsFocusedProperty, value);
        }

    private static void IsFocusedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
        var fe = (FrameworkElement)d;

        // OLD LINE:
        // if (e.OldValue == null)
        // TWO NEW LINES:
        if (BoundElements.Contains(fe.Name) == false)
            {
            BoundElements.Add(fe.Name);
            fe.LostFocus += OnLostFocus;
            fe.GotFocus += OnGotFocus;
            }           


        if (!fe.IsVisible)
            {
            fe.IsVisibleChanged += new DependencyPropertyChangedEventHandler(fe_IsVisibleChanged);
            }

        if ((bool)e.NewValue)
            {
            fe.Focus();             
            }
        }

    private static void fe_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
        var fe = (FrameworkElement)sender;

        if (fe.IsVisible && (bool)((FrameworkElement)sender).GetValue(IsFocusedProperty))
            {
            fe.IsVisibleChanged -= fe_IsVisibleChanged;
            fe.Focus();
            }
        }

    private static void OnLostFocus(object sender, RoutedEventArgs e)
        {
        if (sender != null && sender is Control s)
            {
            s.SetValue(IsFocusedProperty, false);
            }
        }

    private static void OnGotFocus(object sender, RoutedEventArgs e)
        {
        if (sender != null && sender is Control s)
            {
            s.SetValue(IsFocusedProperty, true);
            }
        }
    }
0
user2127475

Sie können das Designmuster ViewCommand verwenden. Es beschreibt eine Methode für das MVVM-Entwurfsmuster zum Steuern einer Ansicht von einem ViewModel mit Befehlen.

Ich habe es auf der Grundlage von King A.Majids Vorschlag implementiert, die MVVM Light Messenger-Klasse zu verwenden. Die ViewCommandManager-Klasse behandelt das Aufrufen von Befehlen in verbundenen Ansichten. Es ist im Grunde die andere Richtung von regulären Befehlen, für diese Fälle, in denen ein ViewModel in seiner Ansicht eine Aktion ausführen muss. Es verwendet Spiegelungen wie datengebundene Befehle und WeakReferences, um Speicherverluste zu vermeiden.

http://dev.unclassified.de/source/viewcommand (auch auf CodeProject veröffentlicht)

0
ygoe

Für Silverlight:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;

namespace MyProject.Behaviors
{
    public class FocusBehavior : Behavior<Control>
    {
        protected override void OnAttached()
        {
            this.AssociatedObject.Loaded += AssociatedObject_Loaded;
            base.OnAttached();
        }

        private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
        {
            this.AssociatedObject.Loaded -= AssociatedObject_Loaded;
            if (this.HasInitialFocus || this.IsFocused)
            {
                this.GotFocus();
            }
        }

        private void GotFocus()
        {
            this.AssociatedObject.Focus();
            if (this.IsSelectAll)
            {
                if (this.AssociatedObject is TextBox)
                {
                    (this.AssociatedObject as TextBox).SelectAll();
                }
                else if (this.AssociatedObject is PasswordBox)
                {
                    (this.AssociatedObject as PasswordBox).SelectAll();
                }
                else if (this.AssociatedObject is RichTextBox)
                {
                    (this.AssociatedObject as RichTextBox).SelectAll();
                }
            }
        }

        public static readonly DependencyProperty IsFocusedProperty =
            DependencyProperty.Register(
                "IsFocused",
                typeof(bool),
                typeof(FocusBehavior),
                new PropertyMetadata(false, 
                    (d, e) => 
                    {
                        if ((bool)e.NewValue)
                        {
                            ((FocusBehavior)d).GotFocus();
                        }
                    }));

        public bool IsFocused
        {
            get { return (bool)GetValue(IsFocusedProperty); }
            set { SetValue(IsFocusedProperty, value); }
        }

        public static readonly DependencyProperty HasInitialFocusProperty =
            DependencyProperty.Register(
                "HasInitialFocus",
                typeof(bool),
                typeof(FocusBehavior),
                new PropertyMetadata(false, null));

        public bool HasInitialFocus
        {
            get { return (bool)GetValue(HasInitialFocusProperty); }
            set { SetValue(HasInitialFocusProperty, value); }
        }

        public static readonly DependencyProperty IsSelectAllProperty =
            DependencyProperty.Register(
                "IsSelectAll",
                typeof(bool),
                typeof(FocusBehavior),
                new PropertyMetadata(false, null));

        public bool IsSelectAll
        {
            get { return (bool)GetValue(IsSelectAllProperty); }
            set { SetValue(IsSelectAllProperty, value); }
        }

    }
}

LoginViewModel.cs:

    public class LoginModel : ViewModelBase
    {
        ....

        private bool _EmailFocus = false;
        public bool EmailFocus
        {
            get
            {
                return _EmailFocus;
            }
            set
            {
                if (value)
                {
                    _EmailFocus = false;
                    RaisePropertyChanged("EmailFocus");
                }
                _EmailFocus = value;
                RaisePropertyChanged("EmailFocus");
            }
        }
       ...
   }

Login.xaml:

xmlns:i="http://schemas.Microsoft.com/expression/2010/interactivity"
xmlns:beh="clr-namespace:MyProject.Behaviors"

<TextBox Text="{Binding Email, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
    <i:Interaction.Behaviors>
        <beh:FocusBehavior IsFocused="{Binding EmailFocus}" IsSelectAll="True"/>
    </i:Interaction.Behaviors>
</TextBox>

OR

<TextBox Text="{Binding Email, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
    <i:Interaction.Behaviors>
        <beh:FocusBehavior HasInitialFocus="True" IsSelectAll="True"/>
    </i:Interaction.Behaviors>
</TextBox>

Um den Fokus zu setzen, tun Sie es einfach im Code:

EmailFocus = true;

Denken Sie daran, dass dieses Plugin Teil einer HTML-Seite ist, sodass andere Steuerelemente auf der Seite möglicherweise den Fokus haben

if (!Application.Current.IsRunningOutOfBrowser)
{
    System.Windows.Browser.HtmlPage.Plugin.Focus();
}
0
ADM-IT

Ich fand die Lösung von Crucial für das IsVisible-Problem sehr nützlich. Es hat mein Problem nicht vollständig gelöst, aber ein paar zusätzliche Codes, die demselben Muster für das IsEnabled-Muster folgen, haben es getan.

Zur IsFocusedChanged-Methode habe ich hinzugefügt:

    if (!fe.IsEnabled)
    {
        fe.IsEnabledChanged += fe_IsEnabledChanged;
    }

Und hier ist der Handler:

private static void fe_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    var fe = (FrameworkElement)sender;
    if (fe.IsEnabled && (bool)((FrameworkElement)sender).GetValue(IsFocusedProperty))
    {
        fe.IsEnabledChanged -= fe_IsEnabledChanged;
        fe.Focus();
    }
}
0
Wayne Maurer