如何从ViewModel wpf中聚焦文本框?
<TextBox Name="PropertySearch"
Text="{Binding UpdateSourceTrigger=PropertyChanged,
Mode=TwoWay, Path=PropertySearch,
ValidatesOnDataErrors=True}"
Width="110"
Height="25"
Margin="10" />
答案 0 :(得分:44)
您可以通过向ViewModel添加属性(或使用现有属性)来指示何时应该发生SetFocus,但View应负责实际设置焦点,因为这纯粹与View相关。
您可以使用DataTrigger执行此操作。
查看:
<Grid Name="LayoutRoot" DataContext="{StaticResource MyViewModelInstance}">
<Grid.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding UserShouldEditValueNow}" Value="True">
<Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=PropertySearch}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
<TextBox Name="PropertySearch" Text="{Binding UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, Path=PropertySearch, ValidatesOnDataErrors=True}" Width="110" Height="25" Margin="10" />
</Grid>
视图模型:
// When you think the view should set focus on a control
this.UserShouldEditValueNow = true;
通过使用布尔ViewModel属性“UserShouldEditValueNow”简化了上面的示例。您可以将这样的属性添加到ViewModel中,或者使用一些指示此状态的其他属性。
注意:那么为什么在MVVM中这样做呢?一个原因是,假设View作者决定用ComboBox替换TextBox,或者甚至更好,假设你的属性是一个整数值,同时有一个TextBox来查看/编辑数字和一个Slider作为另一种编辑相同值的方法,两个控件都绑定到同一个属性...... ViewModel将如何知道要设置焦点的控件? (当它甚至不知道哪个控件或控件首先绑定到它时)这样,View可以通过更改DataTrigger Setter中的ElementName绑定目标来选择要关注的控件。
快乐的编码!
答案 1 :(得分:10)
你应该问自己的问题是“为什么我的ViewModel需要知道哪个控件有焦点?”
我认为焦点是一个只有视图的属性;它是一种交互属性,与概念状态无关。这类似于控件的背景颜色:为什么要在VM中表示它?如果您需要以自定义方式管理焦点,最好使用视图级对象来完成工作。
答案 2 :(得分:3)
在父控件中,添加以下属性:
FocusManager.FocusedElement="{Binding ElementName=PropertySearch}"
答案 3 :(得分:1)
虽然纯粹主义者可能会主张将其从VM中删除,但有时可能会从VM中执行此操作。
我的方法是让视图实现一个接口,将该接口传递给ViewModel,然后让VM调用接口上的方法。
示例:
public interface IFocusContainer
{
void SetFocus(string target);
}
要记住几件事:
要实现界面,您可以:
在Code Behind上实现它没有任何问题,但是如果这对你很重要,那么行为方法只允许XAML连接。
在界面的实现中,您可以使用可视化树来定位控件,或者您可以为一组已知的可聚焦项目编写switch语句。