В моем приложении MVVM у меня есть древовидная структура, представляющая записи в базе данных. Мои представления и модели представления связаны в словаре ресурсов, подобном этому
<DataTemplate DataType="{x:Type vm:TrialSiteViewModel}">
<vw:TrialSiteView />
</DataTemplate>
Я хочу отобразить предварительный просмотр, когда пользователь наводит курсор на значок с помощью всплывающей подсказки. Мой 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, который является DataContext для Treeviewitem.
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. Если я изменю код для использования кнопки Command в TrialSiteViewModel и вставлю его в ObjectPreview, я могу установить contentcontrol в приведенном ниже коде и использовать TrialSiteView.
Я предполагаю, что шаблон каким-то образом выведен из TreeViewItem. Может кто-нибудь сказать мне, как я могу убедиться, что подсказка использует TrialSiteView?
UPDATE
Хорошо, я исправил это, но мне пришлось прибегнуть к коду позади, удалить пользовательский контроль и поместить представление прямо во всплывающую подсказку. Ключевым битом является получение таблицы данных из ресурсов. Я пытался сделать это ранее, назначив ключ к табличке данных, но либо мой код был ошибочным, либо он не работал. В любом случае это работает, но не является предпочтительным решением 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;
}