c# - 如何使用 Caliburn.Micro MVVM 将焦点设置到控件

标签 c# silverlight mvvm caliburn.micro

我有一个表单,我想在发生某些用户操作时将焦点设置到文本框。我知道 MVVM 的做事方式是绑定(bind)到 VM 属性,但是 TextBox 没有允许这种情况发生的属性。从 VM 设置焦点的最佳方法是什么?

最佳答案

我已经创建了一个 IResult 实现,它可以很好地实现这一目标。您可以从 IResult 的 ActionExecutionContext 获取 View ,然后您可以搜索(我按名称搜索)您想要聚焦的控件。

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

viewChildWindow 时,我省略了一些额外的代码以从 context 获取 view如果您需要,我可以提供。

此外,GetChildrenByType 是一种扩展方法,这里是许多可用的实现之一:

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

您的操作将类似于以下内容(以 Caliburn.Micro ActionMessage 样式调用)。

public IEnumerable<IResult> MyAction()
{
    // do whatever
    yield return new GiveFocusByName("NameOfControlToFocus");
}

关于c# - 如何使用 Caliburn.Micro MVVM 将焦点设置到控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4571328/

相关文章:

silverlight - 如何使用代码隐藏变量作为 ValueConverter 中 ConverterParameter 的输入

javascript - 使用 Knockout 从 Json 创建对象时遇到问题

MVVM 绑定(bind)密码

C# sqlite 无法加载sqlite3.dll

c# - 将 Excel 2010 插件转换为 2007 插件(均为 VSTO)

c# - 如何使用 MySQL 连接器在 C# 中获取 NOW() 值?

c# - 从 SAML 断言中提取 SecurityToken

silverlight - 该文件不是项目的一部分或其构建操作属性未设置为资源

jquery - 使用 jQuery 创建 Silverlight 容器 - 在 IE9 中不起作用

javascript - 如何获取从一个JS文件到viewModels的另一个JS以及主JS文件中存在的值?