So konzentrieren Sie sich auf eine Kontrolle mit Caliburn.Micro MVVM
-
14-10-2019 - |
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?
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");
}