0

Я работаю над элементом управления Treeview. Элемент управления должен отображать набор текстовых полей и combobox динамически в зависимости от значения структуры данных. Выполняется преобразование кода ArgumentTypeTemplateSelector. однако текстовое поле и комбо не отображаются. Пожалуйста, помогите кому-нибудь. Спасибо.WPF DataTemplate Селектор не работает

Дерево Вид (XAML)

    <ItemsControl x:Name="argumentTexts" ItemsSource="{Binding ArgumentDetailsCollection}"> 
         <ItemsControl.ItemsPanel> 
          <ItemsPanelTemplate> 
           <StackPanel HorizontalAlignment="Stretch" IsItemsHost="True" Orientation="Horizontal"/> 
          </ItemsPanelTemplate> 
         </ItemsControl.ItemsPanel> 
         <ItemsControl.ItemTemplate> 
          <DataTemplate DataType="{x:Type structures:ArgumentDetails}"> 
           <ItemsControl x:Name="items" ItemsSource="{Binding DefaultValue}" 
               ItemTemplateSelector="{Binding DefaultValue, Converter={StaticResource ArgTypeTemplateSelector}}"/> 
          </DataTemplate> 
         </ItemsControl.ItemTemplate> 
        </ItemsControl> 


public class ArgumentTypeTemplateSelector : IValueConverter 
{ 
    private DataTemplate comboboxDataTemplate; 

    private DataTemplate textboxDataTemplate; 

    public DataTemplate ComboBoxDataTemplate 
    { 
     get 
     { 
      return this.comboboxDataTemplate; 
     } 

     set 
     { 
      this.comboboxDataTemplate = value; 
     } 
    } 

    public DataTemplate TextBoxDataTemplate 
    { 
     get 
     { 
      return this.textboxDataTemplate; 
     } 

     set 
     { 
      this.textboxDataTemplate = value; 
     } 
    } 

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     string str = (string)value; 

     if (str.Contains("1")) 
     { 
      return this.ComboBoxDataTemplate; 
     } 

     return this.TextBoxDataTemplate; 
    } 

В ResourceDictionary (XAML)

 <DataTemplate x:Key="TextBoxDataTemplate"> 
      <TextBox Text="{Binding DefaultValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
             VerticalAlignment="Center" 
             Width="Auto" 
             Margin="5,0,0,0" 
             Padding="0" 
             Style="{StaticResource GridEditStyle}" 
             IsEnabled="True"/> 
     </DataTemplate> 
     <DataTemplate x:Key="ComboBoxDataTemplate"> 
      <ComboBox HorizontalAlignment="Stretch" IsEnabled="True"/> 
     </DataTemplate> 
     <columnConfiguratorControls:ArgumentTypeTemplateSelector x:Key="ArgTypeTemplateSelector" ComboBoxDataTemplate="{StaticResource ComboBoxDataTemplate}" TextBoxDataTemplate="{StaticResource TextBoxDataTemplate}"/> 
    </ResourceDictionary> 
+0

Ваш селектор шаблонов должен реализовывать 'DataTemplateSelector' или что-то в этом роде, а не' IValueConverter', это для преобразователей. Проверьте это http://tech.pro/tutorial/807/wpf-tutorial-how-to-use-a-datatemplateselector. – elnigno

+0

Неправильное использование свойства зависимостей 'ItemTemplateSelector'. Возможно, вам вообще не нужен «ItemTemplateSelector». Каковы критерии, на которых должен основываться выбор DataTemplate? – dymanoid

+0

Dymanoid: это для ввода пользователем и происходит, когда пользователь выбирает элемент в элементе управления древовидной структурой. Если структура данных содержит определенный тип перечисления, я хотел бы изменить текстовый блок в элементе treeview в поле со списком, содержащее список перечислений. Если структура данных содержит тип double или int, я бы хотел отобразить текстовое поле. Структура данных может содержать список перечислений и двойной. Должен ли я использовать выбор DataTemplate для выполнения этой работы? Спасибо – user3753452

ответ

2

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

Попробуйте следующее: В файле XAML определить свой DataTemplateSelector как статический ресурс и установить его в ItemsControl:

<ItemsControl x:Name="argumentTexts" ItemsSource="{Binding ArgumentDetailsCollection}"> 
     <ItemsControl.Resources> 
      <!-- define your template selector as static resource to reference it later --> 
      <ns:ArgumentTypeTemplateSelector x:Key="ArgumentTypeTemplateSelector"/> 
     </ItemsControl.Resources> 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
       <StackPanel HorizontalAlignment="Stretch" IsItemsHost="True" Orientation="Horizontal"/> 
      </ItemsPanelTemplate> 
     </ItemsControl.ItemsPanel> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate DataType="{x:Type structures:ArgumentDetails}"> 
       <!-- use your template selector here --> 
       <ItemsControl x:Name="items" ItemsSource="{Binding DefaultValue}" 
           ItemTemplateSelector="{StaticResource ArgumentTypeTemplateSelector }"/> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
    </ItemsControl> 

В коде позади файла, вам необходимо реализовать данные выбора шаблона, например, в следующим образом:

// derive from base class DataTemplateSelector 
public class ArgumentTypeTemplateSelector : DataTemplateSelector 
{ 
    // override SelectTemplate method 
    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     // get access to the resources you need, for example 
     // by accessing the UI object where your selector is placed in 
     var frameworkElement = (FrameworkElement) container; 

     // return a data template depending on your custom logic, 
     // you can cast "item" here to the specific type and check your conditions 
     if(item has condition) 
     return (DataTemplate) frameworkElement.FindResource("YourDataTemplateKey"); 
     else 
      // ... 
     return base.SelectTemplate(item, container); 
    } 
}