2014-07-10 3 views
0

У меня возникла проблема с созданным пользователем элементом управления. Этот элемент управления состоит из текстового поля поиска и дерева. В дереве показаны разные шаблоны данных для разных типов узлов. Поэтому я создал usercontrol с свойством зависимости типа datatemplate, которое может быть связано при использовании моего элемента управления. Внутри элемента управления древовидная привязка привязывается к свойству зависимости. Но, к сожалению, селектор treeviewtemplate не вызван.Установите ItemTemplateSelector дерева в пользовательский элемент управления

<UserControl x:Class="yyy.yyy.yyy.UI.UserControls.SearchableTreeView.SearchableTreeView" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:behaviours="clr-namespace:yyy.yyy.yyy.UI.Behaviours;assembly=yyy" 
     mc:Ignorable="d" 
     x:Name="parent" 
     d:DesignHeight="300" d:DesignWidth="300"> 
<DockPanel DataContext="{Binding ElementName=parent}"> 
    <TextBox DockPanel.Dock="Top" Margin="5" Text="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}"/> 
    <TreeView DockPanel.Dock="Top" Margin="5" ItemsSource="{Binding TreeViewItems}" ItemTemplateSelector="{Binding TreeViewTemplateSelector}"> 
     <TreeView.ItemContainerStyle> 
      <Style TargetType="{x:Type TreeViewItem}"> 
       <Setter Property="HorizontalContentAlignment" Value="Left" /> 
       <Setter Property="VerticalContentAlignment" Value="Center" /> 
       <Setter Property="behaviours:TreeViewItemBehaviour.IsBroughtIntoViewWhenSelected" Value="true"/> 
       <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" /> 
       <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" /> 
       <Setter Property="FontWeight" Value="Normal" /> 
       <Setter Property="Visibility" Value="Visible"/> 
       <Style.Triggers> 
        <Trigger Property="IsSelected" Value="True"> 
         <Setter Property="FontWeight" Value="Bold" /> 
        </Trigger> 
        <DataTrigger Binding="{Binding Path=IsVisible}" Value="false"> 
         <Setter Property="Visibility" Value="Collapsed"/> 
        </DataTrigger> 
       </Style.Triggers> 
      </Style> 
     </TreeView.ItemContainerStyle> 
    </TreeView> 
</DockPanel> 

Код сзади свойства зависимостей выглядит следующим образом:

public partial class SearchableTreeView : UserControl 
    { 
public SearchableTreeView() 
{ 
    InitializeComponent(); 
} 

public static readonly DependencyProperty TreeViewTemplateSelectorProperty = DependencyProperty.Register(
    "TreeViewTemplateSelector", typeof (DataTemplateSelector), typeof (SearchableTreeView), new PropertyMetadata(default(DataTemplateSelector))); 

public DataTemplateSelector TreeViewTemplateSelector 
{ 
    get { return (DataTemplateSelector) GetValue(TreeViewTemplateSelectorProperty); } 
    set { SetValue(TreeViewTemplateSelectorProperty, value); } 
} 


} 

И UserControl используется в XAML, как что:

<searchableTreeView:SearchableTreeView TreeViewTemplateSelector="{StaticResource TreeViewFieldTemplateSelector}"/> 

Где TreeViewFieldTemplateSelector является классом типа datatemplateselector, который уже работал ранее tartet для создания usercontrol из дерева с возможностью поиска.

Кто-нибудь знает, что я делаю неправильно? Или невозможно привязать элемент данных к элементу непосредственно к древовидной структуре?

Благодаря

Manuel

ответ

1

Вы усложняя систему с помощью DataTemplateSelector. В то время как это является истинным, что эти объекты были созданы для этой цели, есть намного более простой способ для достижения ваших требований. В принципе, если вы объявляете DataTemplate для каждого типа данных без указания x:Key значения, то они будут применяться неявно ко всем объектам правильного типа:

<DataTemplate DataType="{x:Type YourPrefix:YourDataType"> 
    ... 
</DataTemplate> 
<DataTemplate DataType="{x:Type YourPrefix:YourOtherDataType"> 
    ... 
</DataTemplate> 
<DataTemplate DataType="{x:Type YourPrefix:SomeOtherDataType"> 
    ... 
</DataTemplate> 

Теперь, если вы поставите элементы этих типов данных в сбор и привязку данных к элементу управления коллекцией, вы увидите, что ваши различные элементы отображаются как ожидалось, но без осложнений DataTemplateSelector.


UPDATE >>>

Хорошо, попробуйте это вместо того, чтобы ... сначала удалить настройку DataContext="{Binding ElementName=parent}", а затем добавить RelativeSource Binding для TreeViewTemplateSelector собственности:

<DockPanel> 
    <TextBox DockPanel.Dock="Top" Margin="5" Text="{Binding SearchText, 
     UpdateSourceTrigger=PropertyChanged}"/> 
    <TreeView DockPanel.Dock="Top" Margin="5" ItemsSource="{Binding TreeViewItems}" 
     ItemTemplateSelector="{Binding TreeViewTemplateSelector, RelativeSource={ 
     RelativeSource AncestorType={x:Type YourPrefix:SearchableTreeView}}}"> 
     <TreeView.ItemContainerStyle> 
      ... 
     </TreeView.ItemContainerStyle> 
    </TreeView> 
</DockPanel> 
+0

Я знаю, что бы быть проще, но проблема в том, что я должен выбрать DataTemplate, не относящийся к разным типам объектов. В объекте есть свойство, которое используется DataTemplateSelector для указания wpf, который он должен использовать. – Maniga

+0

Thx! Вот и все. Я нашел это решение несколько минут назад там http://www.jayway.com/2011/05/17/bind-from-xaml-to-property-defined-in-code-behind/ Проблема заключалась в том, что у меня было привязать древовидное представление к свойству зависимости, которое находится внутри моего кода за файлом, но контекст данных был моделью представления для элемента управления. – Maniga

Смежные вопросы