如何在不指定TextBox
的名称的情况下将焦点设置为TextBox
?目前我正在做以下事情
<Window FocusManager.FocusedElement="{Binding ElementName=Username}">
<Grid>
<TextBox Text="{Binding Username}" Name="Username" />
</Grid>
</Window>
如果没有为TextBox
指定名称,有没有办法做到这一点。我相信具有Name元素的MVVM通常意味着糟糕的设计?
答案 0 :(得分:21)
我相信MVVM中有一个Name元素通常意味着糟糕的设计?
不,不是。
MVVM模式不是要从代码隐藏文件中删除所有代码。
关注问题的分离和提高可测试性。 查看焦点处理等相关代码应保留在View的代码隐藏文件中。但是在View的代码隐藏文件中看到应用程序逻辑或数据库连接管理会很糟糕。
可以在 WPF Application Framework (WAF) 项目中找到MVVM示例,其中包含代码隐藏文件中的代码而不违反MVVM模式。
答案 1 :(得分:6)
简单的方法是在UserControl_Load事件中设置焦点
this.txtBox.Focus();
txtBox.Focusable = true;
Keyboard.Focus(txtBox);
MVVM并不意味着您无法将代码放在代码隐藏文件中。 事实上,不要让任何模式限制你找到最好的编码方式。
答案 2 :(得分:3)
我在a similar problem的回答中记录了一种“纯MVVM”方式。该解决方案涉及使用附加属性和框架将接口命令从ViewModel传递回View。
答案 3 :(得分:3)
应尽可能避免代码落后,甚至在视图中更多。我有同样的问题,出于简单的目的,最好的答案就是这个,因为它只修改了视图:
WPF MVVM Default Focus on Textbox and selectAll
如果您希望在与其他UserControl元素交互时再次设置焦点,则可以解决这个问题:
Set focus on textbox in WPF from view model (C#)
我失去了3天来解决这个问题,我希望这会有所帮助。
答案 4 :(得分:0)
实际上,我发现布尔附加属性解决方案有点脏和笨拙的方式,你必须找到一个扭曲,以确保下一组视图模型属性将真正引发附加属性更改事件。
一个简单而优雅的解决方案是将您的行为绑定在属性类型上,您可以确保下一个值始终与前一个值不同,从而确保您的附加属性更改事件每次都会引发。
最简单的类型是int。然后解决方案通常是:
的组合行为:
public static 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大小限制有关。好吧......我现在就选择忽略它们; - )
答案 5 :(得分:0)
我相信具有Name元素的MVVM通常意味着糟糕的设计?
不,不是。
据微软MVP称,不仅命名控件是WPF的不良做法,它对性能的影响相当大。只是想传递一些智慧的话语
我同意Sean Du关于不让任何模式完全限制你的观点,我认为应该尽可能避免性能受损。