控件

时间:2016-08-29 21:30:15

标签: c# wpf xaml

我正在尝试创建一个属性编辑器,它可以显示不同数据类型的不同控件。

例如,如果数据是bool,则它应该是一个复选框。如果它是一种颜色,它应该是一个颜色选择器。如果它是一个int,它应该是一个数字向上等。

对于其他一切,它应该是一个文本框< - 这就是我在努力的地方。

对于布尔我可以做

<DataTemplate DataType="{x:Type mscorlib:Boolean}">
    <CheckBox IsChecked="{Binding Path=.}"/>
</DataTemplate>

这完美无缺。

但我无法弄清楚如何使默认文本框发生。

<DataTemplate>
    <TextBlock >
</DataTemplate>

会给我IDictionary必须有一个Key属性错误

如果我向模板添加一个键,除非我明确地执行DataTemplate="..."

之类的操作,否则不会使用它

我似乎找不到给定模板定位多种类型的方法。这迫使我为我希望支持的每种类型反复粘贴模板。

有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

Most professional way of doing this to use templateselector.

Use the IntegerUpDown control in the xtended wpf toolkit for numeric up and down

Use the colorpicker control of xtended wpf toolkit for color picker

Include this in xaml

    xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"



          <DataTemplate x:Key="TEMPLATE">
                            <TextBox Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}" />
                        </DataTemplate>
                        <DataTemplate x:Key="BOOLEANTEMPLATE">
                            <CheckBox IsChecked="{Binding Value, UpdateSourceTrigger=PropertyChanged}" />
                        </DataTemplate>
                  <DataTemplate x:Key="numericTemplate">
                       <xctk:IntegerUpDown Name="myUpDownControl" />
                    </DataTemplate>
                     <DataTemplate x:Key="ColorTemplate">
                        <xctk:ColorPicker></xctk:ColorPicker>
                    </DataTemplate>
                        <me:DynamicDataTemplateSelector        x:Key="datagridDynamictemplateselector"                                                     BooleanTemplate="{StaticResource BOOLEANTEMPLATE}"
ColorTemplate ="{StaticResource ColorTemplate}"
NumericTemplate ="{StaticResource numericTemplate}"
                                                        TextBoxTemplate="{StaticResource TEMPLATE}" />

Here is the class which override datatemplateselector class

  public class DynamicDataTemplateSelector : DataTemplateSelector
        {
            public DataTemplate TextBoxTemplate{get;set;}
            public DataTemplate BooleanTemplate{get;set;}

            public DataTemplate NumericTemplate { get; set; }
            public DataTemplate ColorTemplate { get; set; }
            public override DataTemplate SelectTemplate(object item, DependencyObject container)
            {
                DataTemplate dataTemplate = TextBoxTemplate;
                  if(item!=null)
                  {                  
                      Type dataTypeOfValue = item.GetType();

                        if(dataTypeOfValue==typeof(int))
                       {
                           dataTemplate = NumericTemplate;
                       }
                       else if(dataTypeOfValue==typeof(Color))
                       {
                           dataTemplate = ColorTemplate;
                       }

                       else if (dataTypeOfValue == typeof(Boolean) || dataTypeOfValue == typeof(bool))
                        {
                            dataTemplate = BooleanTemplate;
                        }

                  }
                 return dataTemplate;
            }

答案 1 :(得分:0)

我使用xaml style + converter解决了这个问题。

<ContentPresenter Content="{Binding MyValue}" 
    <ContentPresenter.Style>
         <Style TargetType="ContentPresenter">
               <Style.Setters>
                    <Setter Property="ContentTemplate">
                           <Setter.Value>
                                <DataTemplate>
                                     <TextBox Text="Dead beef"/>
                                </DataTemplate>
                           </Setter.Value>
                   </Setter>
               </Style.Setters>
         <Style.Triggers>
               <DataTrigger Binding="{Binding Path=., Converter={StaticResource ToTypeConverter}}" Value="{x:Type mscorlib:Boolean}">
                      <Setter Property="ContentTemplate">
                            <Setter.Value>
                                  <DataTemplate>
                                       <CheckBox IsChecked="{Binding Path=.}"/>
                                  </DataTemplate>
                            </Setter.Value>
                      </Setter>
                 </DataTrigger>
           </Style.Triggers>
       </Style>
   </ContentPresenter.Style>
</ContentPresenter>

转换器

public class ToTypeConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (value == null) ? null : value.GetType();
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

我们的想法是将默认模板放在样式的ContentTemplate中,并仅使用样式触发器修改特殊模板。