MVVM Focus To Textbox

MVVM Focus To Textbox

问题描述:

如何将焦点设置为TextBox而不指定该名称TextBox?目前,我做了以下MVVM Focus To Textbox

<Window FocusManager.FocusedElement="{Binding ElementName=Username}"> 
    <Grid> 
     <TextBox Text="{Binding Username}" Name="Username" />    
    </Grid> 
</Window> 

是否有这样做而没有指定名称为TextBox的任何方式。因为我认为MVVM具有Name元素通常意味着糟糕的设计?

+0

我不认为有一个元素的名称本身就是不好的设计,但给元素一个名称,以便您可以在代码隐藏中引用它,应该避免。我没有看到上面的观点有什么不妥。 – lesscode 2010-05-14 14:50:06

+0

考虑是否要使用触发器在视图中执行任何特殊操作(动画和其他状态更改) - 名称对于这些操作非常重要。 – Gusdor 2011-07-26 12:36:28

我在a similar problem的回答中记录了一个“纯MVVM”的方法。该解决方案涉及使用附加属性以及将视图模型中的界面命令传递回视图的框架。

+0

http://geekswithblogs.net/HouseOfBilz/archive/2009/08/27/adventures-in-mvvm-ndash-binding-commands-to-any-event.aspx – Agies 2010-05-21 02:03:40

因为我相信MVVM有一个Name元素通常意味着设计不好?

不,它不是。

MVVM模式不是关于从代码隐藏文件中消除所有代码。

这是关于分离问题和提高可测试性。 查看相关代码,如焦点处理应保留在视图的代码隐藏文件中。但是在View的代码隐藏文件中看到应用程序逻辑或数据库连接管理会很糟糕。

MVVM示例代码隐藏文件中的代码没有违反MVVM模式可以在WPF Application Framework (WAF)项目中找到。

+7

+1 ** MVVM模式是不是消除代码隐藏文件中的所有代码都很好 – ktutnik 2012-07-10 03:22:15

简单的方法是在UserControl_Load事件将焦点设置

 this.txtBox.Focus(); 
     txtBox.Focusable = true; 
     Keyboard.Focus(txtBox); 

MVVM并不意味着你不能把代码隐藏文件中的代码。事实上,不要让任何模式限制你找到最好的编码方式。

实际上,我发现布尔附加属性解决方案有点肮脏和笨拙的方式,你必须找到一个扭曲,以确保下一组视图模型属性将真正引发附加属性更改事件。

一个简单和更优雅的解决方案是绑定你的行为属性类型,你可以确保下一个值将永远不同于前一个,从而确保你的附属属性改变事件会每次提升。

想到的最简单的类型是int。然后将溶液的通常的组合:

行为:

class TextBoxFocusBehavior 
{ 
    public static int GetKeepFocus(DependencyObject obj) 
    { 
     return (int)obj.GetValue(KeepFocusProperty); 
    } 

    public static void SetKeepFocus(DependencyObject obj, int value) 
    { 
     obj.SetValue(KeepFocusProperty, value); 
    } 

    // Using a DependencyProperty as the backing store for KeepFocus. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty KeepFocusProperty = 
     DependencyProperty.RegisterAttached("KeepFocus", typeof(int), typeof(TextBoxFocusBehavior), new UIPropertyMetadata(0, OnKeepFocusChanged)); 

    private static void OnKeepFocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     TextBox t = d as TextBox; 
     if (t != null) 
     { 
      t.Focus(); 
     } 
    } 
} 

视图模型属性:

public int InputFocus 
    { 
     get { return _inputFocus; } 
     private set 
     { 
      _inputFocus = value; 
      Notify(Npcea.InputFocus); 
     } 
    } 

使用该附加的行为的:

<TextBox v:TextBoxFocusBehavior.KeepFocus="{Binding InputFocus}"/> 

而最终使用VM中的财产:

public void YouMethod() 
    { 
     //some code logic 
     InputFocus++;//<= the textbox focus 
    } 

一些非常坏的思想精神可以说,这种逻辑被绑定到INT32大小限制。那么......我现在就选择忽略它们;-)

因为我相信MVVM有一个Name元素通常意味着糟糕的设计?

不,不是。

根据微软MVP的命名控件不仅是WPF不好的做法,它是一个相当大的性能打击。只是想沿着智慧

有些话我与肖恩·杜同意关于不让任何模式完全限制你通过了,我觉得应该尽量避免性能下降。

尽可能地避免后面的代码,甚至在视图中时更多。我有同样的问题,并进行简单的目的,最好的回答是,因为它只是修改视图这一个:

WPF MVVM Default Focus on Textbox and selectAll

如果您正在寻找重新设置焦点,你与其他用户控件元素进行交互,这是不行的诀窍:

Set focus on textbox in WPF from view model (C#)

我失去了3天搞清楚了这一点,我希望这可以帮助。