首页 > 其他分享 >WPF MVVM模式下如何给Textbox设置焦点(GalaSoft.MvvmLight)

WPF MVVM模式下如何给Textbox设置焦点(GalaSoft.MvvmLight)

时间:2022-12-02 10:00:11浏览次数:53  
标签:控件 sender MVVM element FrameworkElement static fe MvvmLight WPF


项目场景:

最近在使用WPF MVVM模式进行开发的时候遇到了个头大的问题,就是如何通过VM去驱动V里面的试图控件,例如最简单的通过VM里面去控制前端页面里面的文本框焦点问题,平常简单的一句话现在就感觉变得异常复杂,由于也是半路接手别人的项目,里面各种封装控件组件,遇到棘手的问题就头大。好在通过网络查找到了最终的解决方案。现做个记录,方便后期查漏补缺。

解决方案:

解决方案一:通过​​Messenger​​类通过发布订阅的方式解决

这种方式比较易于理解,学过web前端编程的小伙伴应该都习惯用这种方式来进行数据驱动,唯一的缺点就是破坏了xmal.cs 里面无代码的环境,导致代码耦合度又变高了,不易于后期维护。而且代码不通用,无法复用到别的页面里面。

在VM里面发布消息(ViewModel.cs文件)

Messenger.Default.Send<string>("focus", "DoFocus");

在V里面订阅消息(view.xaml.cs)

public MyView()
{
InitializeComponent();

Messenger.Default.Register<string>(this, "DoFocus", doFocus);
}
public void doFocus(string msg)
{
if (msg == "focus")
this.txtcode.Focus();
}

下面这种方法扩展性更强一些,可以快速实现不通控件的焦点事件处理

解决方案二:通过扩展控件属性来完成

扩展控件属性类,里面具体包含如下方法

public static class FocusExtension
{
public static readonly DependencyProperty IsFocusedProperty =
DependencyProperty.RegisterAttached("IsFocused", typeof(bool?), typeof(FocusExtension), new FrameworkPropertyMetadata(IsFocusedChanged){BindsTwoWayByDefault = true});

public static bool? GetIsFocused(DependencyObject element)
{
if (element == null)
{
throw new ArgumentNullException("element");
}

return (bool?)element.GetValue(IsFocusedProperty);
}

public static void SetIsFocused(DependencyObject element, bool? value)
{
if (element == null)
{
throw new ArgumentNullException("element");
}

element.SetValue(IsFocusedProperty, value);
}

private static void IsFocusedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var fe = (FrameworkElement)d;

if (e.OldValue == null)
{
fe.GotFocus += FrameworkElement_GotFocus;
fe.LostFocus += FrameworkElement_LostFocus;
}

if (!fe.IsVisible)
{
fe.IsVisibleChanged += new DependencyPropertyChangedEventHandler(fe_IsVisibleChanged);
}

if ((bool)e.NewValue)
{
fe.Focus();
}
}

private static void fe_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
var fe = (FrameworkElement)sender;
if (fe.IsVisible && (bool)((FrameworkElement)sender).GetValue(IsFocusedProperty))
{
fe.IsVisibleChanged -= fe_IsVisibleChanged;
fe.Focus();
}
}

private static void FrameworkElement_GotFocus(object sender, RoutedEventArgs e)
{
((FrameworkElement)sender).SetValue(IsFocusedProperty, true);
}

private static void FrameworkElement_LostFocus(object sender, RoutedEventArgs e)
{
((FrameworkElement)sender).SetValue(IsFocusedProperty, false);
}
}

我添加可见性引用的原因是标签。显然,如果您在最初可见选项卡之外的任何其他选项卡上使用附加属性,则在手动聚焦控件之前,附加属性不起作用。 另一个障碍是在失去焦点时创建一种更优雅的方法将底层属性重置为false。这就是失去焦点事件的来源。

.xaml文件里面使用

<TextBox            
Text="{Binding Description}"
FocusExtension.IsFocused="{Binding IsFocused}"/>

如果有更好的方法来处理可见性问题,请告诉我。 注意:将BindsTwoWayByDefault放入DependencyProperty中。我很久以前在自己的代码中做过这个。由于此更改,WPF代码中不再需要Mode = TwoWay。


标签:控件,sender,MVVM,element,FrameworkElement,static,fe,MvvmLight,WPF
From: https://blog.51cto.com/u_11295556/5905029

相关文章

  • MAUI新生2.4-数据绑定和MVVM:MVVM的消息机制
    当两个对象之间需要建立松耦合关系时,特别适合使用消息机制。如ViewModel需要控制View进行某些操作时,如弹出对话框、播放动画,由于ViewModel对View是无感的,我们不能在ViewMod......
  • wpf Datagrid绑定 Dictionary
    原文网址: https://www.cnblogs.com/zany-hui/articles/7623874.html数据源格式:Dictionary<int,List<string>>1.通过xaml设置<DataGridx:Name="dg"ItemsSource="{Bi......
  • WPF中单位
    WPF中单位WPF程序中的单位是与设备无关的单位,每个单位是1/96英寸,如果电脑的DPI(DotsPerInch,每英寸点数)设置为96(每个英寸96个像素),那么此时每个WPF单位对应一个像素,不过如果......
  • WPF 四种尺寸单位
    像素 px默认单位可以省略厘米cm英寸in点pt1in=96px1cm=96/2.42px1pt=96/72px   postedon 2018-08-3011:56 NET未来之路 阅读( ...)评论(......
  • WPF在国内还有希望和前途吗?
    WPF在国内还有希望和前途吗? 为什么大公司不会使用它?QQ出了个概念版还很少更新,wpf是不是没前途了? 作者:匿名用户链接:https://www.zhihu.com/question/26862663/an......
  • .net core/5/6/7中WPF如何优雅的开始开发
    .netcore/5/6/7中WPF如何优雅的开始开发 WPF是微软的.net平台中的一个桌面客户端应用程序框架,经常用于企业开发windows桌面客户端,广泛应用于中小企业快速开发一款......
  • 安卓设计模式演变之经典三层模型(MVC/MVP/MVVM)
    转载请标明出处!先看代码demo再回看文章效果最佳!目录​​一mvc​​​​1.1概述​​​​1.2 作用流程​​​​1.3 现状​​​​1.4致命弱点/缺点:​​​​1.5 代码Demo​......
  • MVVM教程(一):MVVM简介与准备工作
    如果你对MVVM的概念还是不了解,可以参看下面链接:​​​http://baike.baidu.com/view/3507915.htm​​我们以WPF+MVVM的本地桌面程序为背景,这样一来我们可以不去操心服务器那......
  • WPF_MVVM框架(5)
    1.NuGet引用MVVM框架包引入该框架包之后,默认会在目录下创建ViewModel层的示例代码2.第二步,通过在MainViewModel中创建一些业务代码,将其与MainWindow.xaml通过......
  • WPF控件模板(6)
    什么是ControlTemplate?ControlTemplate(控件模板)不仅是用于来定义控件的外观、样式,还可通过控件模板的触发器(ControlTemplate.Triggers)修改控件的行为、响应动画等......