Frage

Ich habe ein Formular und möchte den Fokus auf ein Textfeld setzen, wenn bestimmte Benutzeraktionen stattfinden. Ich weiß, dass die MVVM -Möglichkeit, Dinge zu tun, darin besteht, an VM -Eigenschaften zu binden. Das Textfeld verfügt jedoch über keine Eigenschaft, die dies zulässt. Was ist der beste Weg, um den Fokus von der VM zu stecken?

War es hilfreich?

Lösung

Ich habe eine IRSULT -Implementierung erstellt, die recht gut funktioniert, um dies zu erreichen. Sie können die Ansicht aus dem ActionExecutionContext des IRSULT erhalten, den Sie dann nach der Steuerung suchen können (ich suche nach Namen), das Sie sich konzentrieren möchten.

public class GiveFocusByName : ResultBase
{
    public GiveFocusByName(string controlToFocus)
    {
        _controlToFocus = controlToFocus;
    }

    private string _controlToFocus;

    public override void Execute(ActionExecutionContext context)
    {
        var view = context.View as UserControl;


        // add support for further controls here
        List<Control> editableControls =
                view.GetChildrenByType<Control>(c => c is CheckBox ||
                                                      c is TextBox ||
                                                      c is Button);

        var control = editableControls.SingleOrDefault(c =>
                                                 c.Name == _controlToFocus);

        if (control != null)
        control.Dispatcher.BeginInvoke(() =>
        {
            control.Focus();

            var textBox = control as TextBox;
            if (textBox != null)
                textBox.Select(textBox.Text.Length, 0);
        });

        RaiseCompletedEvent();
    }
}

Ich habe einen zusätzlichen Code, um das zu bekommen view von dem context wenn der view ist ein ChildWindow Ich kann bereitstellen, wenn Sie benötigen.

GetChildrenByType ist auch eine Erweiterungsmethode. Hier ist eine von vielen Implementierungen in freier Wildbahn:

public static List<T> GetChildrenByType<T>(this UIElement element,
                          Func<T, bool> condition) where T : UIElement
{
    List<T> results = new List<T>();
    GetChildrenByType<T>(element, condition, results);
    return results;
}

private static void GetChildrenByType<T>(UIElement element,
                          Func<T, bool> condition, List<T> results) where T : UIElement
{
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
    {
        UIElement child = VisualTreeHelper.GetChild(element, i) as UIElement;
        if (child != null)
        {
            T t = child as T;
        if (t != null)
        {
            if (condition == null)
                results.Add(t);
            else if (condition(t))
            results.Add(t);
        }
        GetChildrenByType<T>(child, condition, results);
        }
    }
}

Ihre Aktion wäre dann so etwas wie das folgende (in Caliburn.Micro ActionMessage -Stil aufgerufen).

public IEnumerable<IResult> MyAction()
{
    // do whatever
    yield return new GiveFocusByName("NameOfControlToFocus");
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top