在我的MVVM应用程序中,我有一个表示数据库中记录的树视图。我的视图和视图模型链接在像这样的资源字典中
<DataTemplate DataType="{x:Type vm:TrialSiteViewModel}">
<vw:TrialSiteView />
</DataTemplate>
当用户使用工具提示悬停在图标上时,我想显示视图的预览。树视图中的My HierarchicalDataTemplate就是这个
<HierarchicalDataTemplate DataType="{x:Type vm:TrialSiteViewModel}"
ItemsSource="{Binding Path=Children}">
...
<Button Style="{StaticResource previewButtonStyle}">
<Button.ToolTip>
<ToolTip Style="{x:Null}">
<ToolTip.ContentTemplate>
<DataTemplate>
<localtools:ObjectPreview
PreviewObject="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TreeViewItem}}, Path=DataContext}"
/>
</DataTemplate>
</ToolTip.ContentTemplate>
</ToolTip>
</Button.ToolTip>
</Button>
</StackPanel>
</HierarchicalDataTemplate>
这正确地选择了TrialSiteViewModel,它是Treeviewitem的DataContext。
ObjectPreview使用viewbox和contentcontrol来显示记录的视图
<Viewbox Grid.Row="1" Name="treeviewViewBox"
Stretch="Uniform"
IsEnabled="False">
<ContentControl Name="treeViewItemViewModel"
Content="{Binding PreviewObject}">
</ContentControl>
</Viewbox>
并且后面的代码包含依赖项属性
public partial class ObjectPreview : UserControl
{
public ObjectPreview()
{
InitializeComponent();
}
public static readonly DependencyProperty _previewObjectProperty =
DependencyProperty.Register("PreviewObject", typeof(TreeViewItemViewModel), typeof(ObjectPreview));
public TreeViewItemViewModel PreviewObject
{
get { return (TreeViewItemViewModel)GetValue(_previewObjectProperty); }
set { SetValue(_previewObjectProperty, value); }
}
}
我遇到的问题是用于显示对象的模板与树视图中使用的模板相同。这只是显示一个图标和一个对象摘要(即主键和一个或两个关键字段),而不是视图TrialSiteView中定义的整个模板。如果我修改代码以在TrialSiteViewModel上使用按钮Command并将其注入ObjectPreview,我可以在后面的代码中设置contentcontrol并使用TrialSiteView。
我猜测模板是从TreeViewItem推断出来的。谁能告诉我如何确保工具提示使用TrialSiteView?
更新
好的,所以我已经解决了这个问题,但不得不求助于代码并删除用户控件并将视图直接放在工具提示中。关键是从资源获取datatemplate。我曾尝试通过为datatemplate分配一个键来执行此操作,但是我的代码有缺陷或无法正常工作。无论如何,这可行,但不是首选的Xaml解决方案。
private void PreviewObject_MouseEnter(object sender, MouseEventArgs e)
{
Image image = (Image)sender;
var key = new System.Windows.DataTemplateKey(image.DataContext.GetType());
var datatemplate = (DataTemplate)this.FindResource(key);
ToolTip tooltip = new ToolTip();
tooltip.Style = VisualUtils.GetResource<Style>("ControlTemplates.xaml", "toolTipWithContentStyle");
tooltip.MaxWidth = 460;
ContentControl contentcontrol = new ContentControl();
contentcontrol.ContentTemplate = datatemplate;
contentcontrol.Content = image.DataContext as TreeViewItemViewModel;
Viewbox viewbox = new Viewbox();
viewbox.Stretch = Stretch.Uniform;
viewbox.Child = contentcontrol;
tooltip.Content = viewbox;
image.ToolTip = tooltip;
}
答案 0 :(得分:0)
您需要做的是明确指定要使用的数据模板。为此,只需在预览控件中添加模板属性以及PreviewObject
属性:
public static readonly DependencyProperty _previewObjectTemplateProperty =
DependencyProperty.Register("PreviewObjectTemplate", typeof(DataTemplate), typeof(ObjectPreview));
public DataTemplate PreviewObjectTemplate
{
get { return (DataTemplate)GetValue(_previewObjectTemplateProperty); }
set { SetValue(_previewObjectTemplateProperty, value); }
}
然后,在ObjectPreview.xaml
中添加绑定到ContentTemplate
属性的PreviewObjectTemplate
属性:
<Viewbox Grid.Row="1" Name="treeviewViewBox"
Stretch="Uniform"
IsEnabled="False">
<ContentControl Name="treeViewItemViewModel"
Content="{Binding PreviewObject}"
ContentTemplate="{Binding PreviewObjectTemplate}" >
</ContentControl>
</Viewbox>
最后,为您的数据模板提供一个密钥,并在声明ObjectPreview
时明确指定对它的引用:
<DataTemplate x:Key="FullViewTemplate" DataType="{x:Type vm:TrialSiteViewModel}">
<vw:TrialSiteView />
</DataTemplate>
...
<ToolTip Style="{x:Null}">
<ToolTip.ContentTemplate>
<DataTemplate>
<localtools:ObjectPreview
PreviewObject="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TreeViewItem}}, Path=DataContext}"
PreviewObjectTemplate="{StaticResource FullViewTemplate}"
/>
</DataTemplate>
</ToolTip.ContentTemplate>