当前位置: 首页 > news >正文

WPF MVVM如何在ViewModel直接操作控件对象

早些年在WPF中使用COM组件时,需要在ViewModel中操作COM组件中的控件对象,但是这个控件对象又不支持绑定,

后面的解决办法是在窗口加载时,将控件对象以参数传递到Loaded事件的处理命令中,然后将这个对象记录下来,后面就可以直接操作这个控件了。

今天同事在使用WebView2的时候,又遇到这个问题,写个文章分享一下,给后续需要的小伙伴提供点参考。

我们创建一个WPF的项目,然后在界面上放置一个WMP控件(Windows Media Player)。

MainWindow.xaml

 1 <Window x:Class="GetControlInViewModel.MainWindow"2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"6         xmlns:wmp="clr-namespace:AxWMPLib;assembly=AxInterop.WMPLib"7         xmlns:local="clr-namespace:GetControlInViewModel"8         mc:Ignorable="d"9         Title="MainWindow" Height="450" Width="800">
10     <Grid>
11         <WindowsFormsHost>
12             <wmp:AxWindowsMediaPlayer x:Name="WMPPlayer"></wmp:AxWindowsMediaPlayer>
13         </WindowsFormsHost>
14     </Grid>
15 </Window>

如果我们想在ViewModel中操作这个WMP对象,可以在Loaded事件中添加如下处理

这里我使用了废弃的包MvvmLight来做演示,因为比较简单方便。

1  <i:Interaction.Triggers>
2      <i:EventTrigger EventName="Loaded">
3          <i:InvokeCommandAction Command="{Binding LoadedCommand}" CommandParameter="{Binding ElementName=WMPPlayer}"></i:InvokeCommandAction>
4      </i:EventTrigger>
5  </i:Interaction.Triggers>

ViewModel

 1 public class MainViewModel : ViewModelBase2 {3     private AxWMPLib.AxWindowsMediaPlayer mediaPlayer;4 5     public RelayCommand<AxWMPLib.AxWindowsMediaPlayer> OnLoadedCommand { get; private set; }6     7     public MainViewModel()8     {9         OnLoadedCommand = new RelayCommand<AxWMPLib.AxWindowsMediaPlayer>(OnLoaded);
10     }
11 
12     private void OnLoaded(AxWMPLib.AxWindowsMediaPlayer axWindowsMediaPlayer)
13     {
14         this.mediaPlayer = axWindowsMediaPlayer;
15     }
16 }

然后将ViewModel绑定到MainWindow上,运行时就可以获取到WMP对象

有时我们会遇到控件未初始化,在Loaded事件中无法获取到控件对象,类似下面这样

比如在使用Prism进行区域导航的时候,就可能会出现这个问题。

此时我们可以将整个窗口/用户控件(UserControl)传过来,然后延时一秒,或者延时加循环几次,就可以获取到控件对象

1  private async void OnLoaded(Window window)
2  {
3      await Task.Delay(1000);
4      var webViewElement = window.FindName("WebView");
5      if (webViewElement != null)
6          this.webView = webViewElement as WebView2;
7  }

示例代码

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 详细解说一下Python中的递归和基例
  • JVM面试(二)内存区域划分
  • 在MySQL存储过程中,以下句子需要以分号(;)结尾
  • 后台框架-统一数据格式
  • 网站建设完成后, 做seo必须知道的专业知识之--蜘蛛陷阱
  • 如何防范ddos 攻击
  • 二分查找精炼回顾-kevin
  • 在线压缩pdf,无需安装就可轻易压缩pdf文件
  • Axure RP下载+详细安装步骤资源百度云盘分享
  • Flask框架 完整实战案例 附代码解读 【3】
  • 【CSS】如何写渐变色文字并且有打光效果
  • OceanBase V4.2解析:如何用迭代器 Generator快速生成任意数据
  • DS18B20温度传感器详解(STM32)
  • MySQL基础学习:MySQL主从复制如何实现
  • 在HarmonyOS中灵活运用Video组件实现视频播放
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • iOS帅气加载动画、通知视图、红包助手、引导页、导航栏、朋友圈、小游戏等效果源码...
  • Just for fun——迅速写完快速排序
  • Koa2 之文件上传下载
  • Less 日常用法
  • Spring Cloud Feign的两种使用姿势
  • Vue ES6 Jade Scss Webpack Gulp
  • Vue UI框架库开发介绍
  • 从0到1:PostCSS 插件开发最佳实践
  • 给第三方使用接口的 URL 签名实现
  • 码农张的Bug人生 - 见面之礼
  • 买一台 iPhone X,还是创建一家未来的独角兽?
  • 如何在 Tornado 中实现 Middleware
  • 微服务入门【系列视频课程】
  • # .NET Framework中使用命名管道进行进程间通信
  • # Redis 入门到精通(一)数据类型(4)
  • #162 (Div. 2)
  • #Linux(权限管理)
  • #NOIP 2014#day.2 T1 无限网络发射器选址
  • #systemverilog# 之 event region 和 timeslot 仿真调度(十)高层次视角看仿真调度事件的发生
  • ${ }的特别功能
  • (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作...
  • (二)学习JVM —— 垃圾回收机制
  • (附源码)springboot助农电商系统 毕业设计 081919
  • (附源码)ssm失物招领系统 毕业设计 182317
  • (附源码)计算机毕业设计SSM疫情居家隔离服务系统
  • (求助)用傲游上csdn博客时标签栏和网址栏一直显示袁萌 的头像
  • (算法)区间调度问题
  • (转载)VS2010/MFC编程入门之三十四(菜单:VS2010菜单资源详解)
  • ******IT公司面试题汇总+优秀技术博客汇总
  • .FileZilla的使用和主动模式被动模式介绍
  • .net mvc部分视图
  • .NET 同步与异步 之 原子操作和自旋锁(Interlocked、SpinLock)(九)
  • .net6解除文件上传限制。Multipart body length limit 16384 exceeded
  • .net中应用SQL缓存(实例使用)
  • /usr/bin/python: can't decompress data; zlib not available 的异常处理
  • @converter 只能用mysql吗_python-MySQLConverter对象没有mysql-connector属性’...
  • [ 环境搭建篇 ] 安装 java 环境并配置环境变量(附 JDK1.8 安装包)
  • [ 蓝桥杯Web真题 ]-布局切换