[WPF] 在 ViewModel 中让数据验证出错(Validation.HasError)的控件获得焦点 (2)

上面的做法实现了我的需求,而且使用这种方案可以让 ViewModel 对 View 有更多的控制权,可以指定哪个 UI 元素在任何时间获得焦点,但坏处就是要写很多代码,而且属性越多耦合越多。

另一种做法是让 Validation.HasError 为 true 的控件自动获得焦点,可以在 View 上添加这个样式:

<Style TargetType="TextBox" BasedOn="{StaticResource {x:Type Control}}"> <Style.Triggers> <DataTrigger Binding="{Binding (Validation.HasError),RelativeSource={RelativeSource Mode=Self}}" Value="True"> <Setter Property="FocusManager.FocusedElement" Value="{Binding RelativeSource={RelativeSource Mode=Self}}"/> </DataTrigger> </Style.Triggers> </Style>

ViewModel 中可以不负责处理焦点,只负责验证数据:

private void Submit() { ErrorsContainer.ClearErrors(); if (string.IsNullOrEmpty(Name)) ErrorsContainer.SetErrors(nameof(Name), new List<string> { "请输入名称" }); }

这个全局 Style 让所有 TextBox 都添加一个绑定到 Validation.HasError 的 DataTrigger,当 Validation.HasError 为 True 时 TextBox 获得焦点。这种做法可以写少很多代码,但对具体业务来说可能不是很好用。

6. 最后

这篇文章只介绍了简单的解决方案,最后还是需要根据自己的业务需求进行修改或封装。View 和 ViewModel 交互可以是一个很庞大的话题,下次有机会再深入探讨。

7. 参考

FocusManager.FocusedElement 附加属性

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zywyxj.html