wpf Usercontrol模板

时间:2011-05-09 08:51:50

标签: wpf datatemplate

在我的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;
}

1 个答案:

答案 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>