我正在开发一个 WPF/MVVM 应用程序,它将承载一个 WinForms 图形控件,用于显示 CAD 类型的几何图形。
首先,一点背景。
基本上,我有一个 MainWindow,左边是 TreeView,右边是 TabControl。TreeView 只是呈现 TreeNode 对象的 Observable 集合。根据在树中单击的节点类型,主窗口的 ViewModel 为选定的树节点(“工作区”)创建适当的子 ViewModel 的实例。新的工作区被添加到另一个绑定到 TabControl 的 Observable 集合中——这会创建一个新的选项卡项。这与著名的 Josh Smith 示例非常相似。
在主窗口的 XAML 中,我正在使用<DataTemplate DataType...>
为刚刚创建的 ViewModel 实例化一个适当的 View。
到目前为止,一切都很好。这一切都很好。现在,这就是我被困的地方......
树节点的一种“类型”代表 CAD 模型。When a node of that type is selected, the view that's instantiated contains the WinForms graphical control (wrapped in a WinFormsHost UserControl). 底层 WinForms 控件有一个“LoadFile()”方法,它只需要一个文件名作为输入。
在 MainWindow 中呈现为树节点的对象包含我需要加载的文件的名称。因此,我试图找出从树节点对象中获取文件名并将其传递给底层 WinForms 控件中的“LoadFile()”方法的最佳方法。
在我为 CAD 控件创建 ViewModel 时,我在 MainWindow 的 ViewModel 中有文件名(反过来,它通过 XAML DataTemplate 创建包含 WinForms 控件的视图)。
到目前为止,我所做的每一次尝试都感觉像是把自己画到了一个角落里。那么,我是否已经在杂草中走得太远了,或者这听起来可以挽救吗?
编辑后按以下要求发布代码...
用户控制的相关代码隐藏
public string MSIFile
{
get { return (String)GetValue(MSIFileProperty); }
set { SetValue(MSIFileProperty, value); }
}
public static readonly DependencyProperty MSIFileProperty =
DependencyProperty.Register("MSIFIle", typeof(string), typeof(ViewportUserControl),
new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnMSIFileChanged)));
private static void OnMSIFileChanged(
DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
Console.WriteLine(e);
}
用户控制 XAML
<UserControl x:Class="TruNest.UserControls.ViewportUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vp="clr-namespace:CustomControls;assembly=Winforms"
d:DesignHeight="300"
d:DesignWidth="300"
mc:Ignorable="d" Loaded="UserControl_Loaded">
<Grid>
<WindowsFormsHost HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<vp:ViewportCustomUC x:Name="Wrapper" />
</WindowsFormsHost>
</Grid>
</UserControl>
MainWindow ViewModel 中的代码 - 选择新 TreeNode 时触发
else if (_selectedTreeViewItem is ViewportNode)
{
ViewportNode node = _selectedTreeViewItem as ViewportNode;
ViewportViewModel workspace = new ViewportViewModel();
workspace.TreeNode = _selectedTreeViewItem;
workspace.Name = String.Format("{0}", node.Name);
Workspaces.Add(workspace);
this.SetActiveWorkspace(workspace);
}