Display control dynamically based on related property using WPF

I have a property that is the database data type (char, datetime, int, float, etc.), and I want to change the control used to enter the value of the selected type. So for text values ​​I want TextBoxand for date values ​​I want DatePicker.

One of the ways that I thought about doing this is to have one of each control in my form and install them Visibilityusing the appropriate implementation IValueConverter. I know this will work, but it will generate a lot of code and will not be very enjoyable.

Another way, I thought, was to use ContentPresenterand install its contents with Styleand DataTriggers, but I cannot get it to work.

    <Style x:Key="TypedValueHelper" TargetType="{x:Type ContentPresenter}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=DataType}" Value="Char">
                <Setter Property="Content" Value="???"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=DataType}" Value="Date">
                <Setter Property="Content" Value="???"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=DataType}" Value="Integer">
                <Setter Property="Content" Value="???"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>

If someone can fill in my "???" or suggest a better solution, please.

+5
source share
3 answers

You can make a combination of style with setters and datatemplates. You basically have a start in your code, although I don't think ContentPresenter is the right style control, as it doesn't have a template.

Maybe something like this:

<Style x:Key="TypedValueHelper" TargetType="{x:Type ContentControl}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=DataType}" Value="Char">
                <Setter Property="ContentTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <TextBox Text="{Binding Path=.}" />
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=DataType}" Value="Integer">
                <Setter Property="ContentTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <Slider Maximum="100" Minimum="0" Value="{Binding Path=.}"
                                             Orientation="Horizontal" />
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </DataTrigger>
        </Style.Triggers>
    </Style>

...

<ContentControl Content="{Binding MyValue}"
                        Style="{StaticResource TypedValueHelper}">
+10
source

, DataTemplates Sdry. , , DataTemplate ; , DataTemplates. DataTemplateSelector, MSDN:


" , DataTemplateSelector, DataTemplate , , DataTemplate ".


ContentControl :

   <ContentControl Content="{Binding Path=ReferenceToYourViewModel}" ContentTemplateSelector="{DynamicResource MyTemplateSelector}"/>

MyTemplateSelector:

    public class MyTemplateSelector: DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        FrameworkElement elem = container as FrameworkElement;
        if(elem == null)
        {
            return null;
        }
        if (item == null || !(item is YourViewModel))
        {
            throw new ApplicationException();
        }
        if ((item as YourViewModel).DataType == DataType.Char)
        {
            return elem.FindResource("CharDataTemplate") as DataTemplate;
        }
        if ((item as YourViewModel).DataType == DataType.Date)
        {
            return elem.FindResource("DateDataTemplate") as DataTemplate;
        }
        if ((item as YourViewModel).DataType == DataType.Integer)
        {
            return elem.FindResource("IntegerDataTemplate") as DataTemplate;
        }
        throw new ApplicationException();
    }
}

, , DataTemplates :

   <DataTemplate x:Key="CharDataTemplate" DataType="{x:Type YourViewModel}">Put Your Xaml Here</DataTemplate>
   <DataTemplate x:Key="DateDataTemplate" DataType="{x:Type YourViewModel}">Put Your Xaml Here</DataTemplate>
   <DataTemplate x:Key="IntegerDataTemplate" DataType="{x:Type YourViewModel}">Put Your Xaml Here</DataTemplate>

DataTemplate DataType . , , , .

+5

I would look in DataTemplates. For instance:

<DataTemplate DataType="{x:Type local:Input}">
            <local:InputControl DataContext="{Binding}" />
 </DataTemplate>

 <DataTemplate DataType="{x:Type data:VideoData}">
                <local:VideoControl DataContext="{Binding}"></local:VideoControl>
 </DataTemplate>
0
source

All Articles