我正在开发一个WPF / MVVM应用程序,它将托管一个用于显示CAD类型几何的WinForms图形控件。
首先,一点背景。
基本上,我有一个MainWindow,左边是TreeView,右边是TabControl。 TreeView只是呈现一个TreeNode对象的Observable集合。根据在树中单击的节点类型,主窗口的ViewModel为所选树节点(“工作空间”)创建适当子ViewModel的实例。新工作区将添加到另一个绑定到TabControl的Observable集合中 - 该集合将创建一个新的选项卡项。这与众所周知的约什史密斯案例非常相似。
在主窗口的XAML中,我正在使用<DataTemplate DataType...>
为刚刚创建的ViewModel实例化一个合适的View。
到目前为止,这么好。这一切都运作良好。现在,这就是我被困的地方......
树节点的一个“类型”表示CAD模型。当选择该类型的节点时,实例化的视图包含WinForms图形控件(包装在WinFormsHost UserControl中)。底层的WinForms控件有一个“LoadFile()”方法,只需要一个文件名作为输入。
在MainWindow中呈现为树节点的对象包含我需要加载的文件的名称。所以,我试图找出从树节点对象获取文件名的最佳方法,并将其传递给底层WinForms控件中的“LoadFile()”方法。
在我为CAD控件创建ViewModel时,我在MainWindow的ViewModel中有文件名(反过来,它通过XAML DataTemplate创建包含WinForms控件的View。)
到目前为止,我所做的每一次尝试都让我感觉自己正在把自己画成一个角落。那么,我是否已经在杂草中走得太远,或者这听起来是否可以挽救?
已按照以下要求编辑发布代码...
用户控制的相关代码隐藏
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);
}