Tony
Tony

Reputation: 133

WPF Creating a multi use control

I'm trying to create a WPF window that has a single control and 2 buttons displayed. The control can be either a TextBox, ComboBox or Slider dependent on the type of object selected to launch this window.

Is it possible to do this or will I have to create a window with 3 conrtols and manipulate their position at runtime?

Regards

Tony

additions to original question

My implementation is as follows

<Window.Resources>
        <Style TargetType="TextBox" x:Key="TextBoxTemplate">
            <Setter Value="{Binding ElementName=MyWindow, Path=m_csValue}" />
        </Style>
        <Style TargetType="{x:Type ComboBox}" x:Key="ComboBoxTemplate">
            <Setter Value="{Binding ElementName=MyWindow, Path=ItemsForSelection}" />
        </Style>
        <Style TargetType="{x:Type Slider}" x:Key="SliderTemplate">
            <Setter Value="{Binding ElementName=MyWindow, Path=SliderDetail}" />
        </Style>

        <Style TargetType="{x:Type ContentControl}" x:Key="DisplayValues">
            <!-- Default Template -->
            <Setter Property="ContentTemplate" Value="{StaticResource TextBoxTemplate}" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding ElementName=MyWindow, Path=eType}" Value="{x:Static local:eTagDisplay.Text}">
                    <Setter Property="ContentTemplate">
                        <Setter.Value>
                            <ControlTemplate Template="{StaticResource TextBoxTemplate}" />
                        </Setter.Value>
                    </Setter> 
                 </DataTrigger>
                <!-- DataTrigger Binding="{Binding ElementName=MyWindow, Path=eType}" Value="{x:Static local:eTagDisplay.Combo}">
                    <Setter Property="ContentTemplate">
                        <Setter.Value>
                            <ControlTemplate Template="{StaticResource ComboBoxTemplate}" />
                        </Setter.Value>
                    </Setter>
                </DataTrigger>
                <DataTrigger Binding="{Binding ElementName=MyWindow, Path=eType}" Value="{x:Static local:eTagDisplay.Slider}">
                <Setter Property="ContentTemplate">
                    <Setter.Value>
                        <ControlTemplate Template="{StaticResource SliderTemplate}" />
                    </Setter.Value>
                </Setter>
                </DataTrigger -->
            </Style.Triggers>
        </Style>
</Window.Resources>

<Grid Width="267">
    <StackPanel Name="TagEditor1">
        <!-- Text="{Binding ElementName=MyWindow, Path=m_csValue}" / -->
        <ContentControl Style="{StaticResource DisplayValues}" />
    </StackPanel>


    <Button Content="OK" Height="23" HorizontalAlignment="Left" Margin="12,154,0,0" Name="btnOK" VerticalAlignment="Top" Width="75" Click="OnClkOK" />
    <Button Content="Cancel" Height="23" HorizontalAlignment="Left" Margin="180,154,0,0" Name="btnCancel" VerticalAlignment="Top" Width="75" Click="OnClkCancel" IsCancel="True" />
</Grid>

I'm getting an error 'System.Windows.Style' is not a valid value for the 'System.Windows.Controls.ContentControl.ContentTemplate' property on a setter. I don't know why this is happening. My Binding is OK, i believe, as it picks up string OK....

Upvotes: 1

Views: 436

Answers (2)

Rachel
Rachel

Reputation: 132618

I would do this with a <ContentControl> that has a different <ContentTemplate> depending on what type of control is needed.

You didn't specify how the control type is being passed to the window, so your DataTrigger bindings would probably look a bit different from mine, but this should give you the right idea:

<DataTemplate TargetType="{x:Type ContentControl}" x:Key="TextBoxTemplate">
    <TextBox ... />
</DataTemplate>
<DataTemplate TargetType="{x:Type ContentControl}" x:Key="ComboBoxTemplate">
    <ComboBox ... />
</DataTemplate>
<DataTemplate TargetType="{x:Type ContentControl}" x:Key="SliderTemplate">
    <Slider ... />
</DataTemplate>

<Style x:Key="MyStyle" TargetType="{x:Type ContentControl}">
    <!-- Default Template -->
    <Setter Property="ContentTemplate" 
            Value="{StaticResource TextBoxTemplate}" />

    <Style.Triggers>
        <DataTrigger Binding="{Binding SomeBoundValue}" Value="ComboBox">
            <Setter Property="ContentTemplate" 
                    Value="{StaticResource ComboBoxTemplate}" />
        </DataTrigger>
        <DataTrigger Binding="{Binding SomeBoundValue}" Value="Slider">
            <Setter Property="ContentTemplate"
                    Value="{StaticResource SliderTemplate}" />
        </DataTrigger>
    </Style.Triggers>
</Style>

...

<ContentControl Style="{StaticResource MyStyle}" />

You could also allow users to specify a Content for your UserControl or Window, and simply display it using a ContentPresenter bound to the Content. Something like this:

<UserControl.Template>
    <StackPanel>
        <ContentPresenter Content="{TemplateBinding Content}" />
        <Button ... />
        <Button ... />
    </StackPanel>
</UserControl.Template>

then you could use it like this:

<local:MyUserControl>
    <TextBox ... />
</local:MyUserControl>

<local:MyUserControl>
    <ComboBox ... />
</local:MyUserControl>

<local:MyUserControl>
    <Slider ... />
</local:MyUserControl>

Upvotes: 3

Sai
Sai

Reputation: 176

I think it is possible with single window.By exposing a property that sets visibilty based on some condition. i.e textbox visibility is set to visibility.visible and combobox,slider visibilty is set to visibility.collpased.similarly if you want to have combobox visible you make that visible and others collapsed.similarly for slider.

example:

  public Visibility TextboxVisibility
    {
        set
        {
            Visibility visible = value;
            Textboxname.Visibility = visible ;
        }
    }

I hope this answers your question

Upvotes: 1

Related Questions