VB.NET WPF如何获取其他UserControl实例以实现多控件打印
可行解决方案
方案1:直接创建新的RollEnd实例(推荐,符合MVVM)
打印只需要渲染UserControl的内容,无需复用界面上已有的实例,直接用现有ViewModel创建新实例即可,彻底避免实例获取问题:
' 在General.xaml.vb的打印逻辑中 Dim rollEndVm = _mainViewModel.RollEndViewModel Dim rollEndControl = New RollEnd(rollEndVm) ' 必须先执行布局测量和排列,确保控件内容正确渲染 rollEndControl.Measure(New Size(Double.PositiveInfinity, Double.PositiveInfinity)) rollEndControl.Arrange(New Rect(rollEndControl.DesiredSize)) ' 渲染到位图 bitmaps.Add(RenderWindowToBitmap(rollEndControl, scaleFactor))
注意:创建UserControl后必须调用
Measure和Arrange,否则控件未完成布局,渲染结果为空。
方案2:通过Application获取MainWindow实例调用方法
如果需要复用界面上已有的RollEnd实例,可通过Application.Current.MainWindow获取MainWindow,再调用其提供的获取方法:
' 在General.xaml.vb的打印逻辑中 Dim mainWindow = TryCast(Application.Current.MainWindow, MainWindow) If mainWindow IsNot Nothing Then Dim rollEndControl = mainWindow.GetRollEndControl() If rollEndControl IsNot Nothing Then bitmaps.Add(RenderWindowToBitmap(rollEndControl, scaleFactor)) End If End If
方案3:使用事件传递实例
若不想直接依赖MainWindow类型,可通过事件实现实例传递:
- 在General中定义事件:
Public Event RequestRollEndControl As Action(Of RollEnd) ' 打印时触发事件 RaiseEvent RequestRollEndControl(Sub(rollEnd) If rollEnd IsNot Nothing Then bitmaps.Add(RenderWindowToBitmap(rollEnd, scaleFactor)) End If End Sub)
- 在MainWindow中订阅事件:
' MainWindow构造函数中 Dim generalControl = FindUserControl(Of General)(Me) If generalControl IsNot Nothing Then AddHandler generalControl.RequestRollEndControl, Sub(callback) callback(_rollEndControl) End Sub End If
之前方法失败的原因
- 方法1(ViewModel存View实例):违反MVVM设计原则,且若实例未添加到视觉树,控件未完成布局,会导致渲染异常或实例状态错误。
- 方法2(视觉树遍历):RollEnd属于MainWindow的视觉子树,而非General的子树,从General开始遍历自然找不到。
- 方法3(MainWindow提供方法):大概率是General中未正确获取MainWindow实例,导致调用方法返回null。
内容的提问来源于stack exchange,提问作者Tim D
相关产品推荐
相关产品推荐

