2
votes

I'm fairly new to WPF and I'm not sure how to do what I want to do.

I've built a custom control that I call a Volume Control. It has 2 RepeatButtons in it, 1 for increasing the value of the Volume property, 1 for decreasing it, and a ProgressBar for giving a visual representation of the current Volume. The control has a property called "Orientation" of type Orientation. When it's Horizontal, I want the control to be drawn one way, and when it's Vertical, I want it to appear different.

In horizontal mode, the control will simply put the 3 controls in a horizontal StackPanel. The Vertical appearance is a bit more complicated, as it's got a Grid in it with 2 columns & 2 rows. The 2 RepeatButtons are stacked on top of each other on the left, while the ProgressBar spans both rows & is on the right.

I can't seem to figure out how to make the control change its appearance based on the value of the Orientation property. Here's what I've got so far:

<Style x:Key="Horizontal" TargetType="{x:Type cs:VolumeControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type cs:VolumeControl}">
                <StackPanel Orientation="Horizontal">
                    ...
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style x:Key="Vertical" TargetType="{x:Type cs:VolumeControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type cs:VolumeControl}">
                <Grid>
                    ...
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

I know I need to something like this in order to define the default template and the necessary trigger for the Orientation property:

<Style TargetType="{x:Type cs:VolumeControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type cs:VolumeControl}">
                <ControlTemplate.Triggers>
                    <Trigger Property="Orientation" Value="Horizontal">
                        ???
                    </Trigger>

                    <Trigger Property="Orientation" Value="Vertical">
                        ???
                    </Trigger>

                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
        </Setter.Value>
    </Setter>
</Style>

I don't know what to put into the two Trigger tags to make it work. Or even if I've got it any of it right.

I've looked at the template for ProgressBar and that uses a RotationTransform to draw the control vertically when the Orientation is set to Vertical. I can't do that as the intent is to draw the control in a different layout.

Any help is appreciated.

Tony

2

2 Answers

5
votes

create 2 control templates

<ControlTemplate x:Key="Horizontal" TargetType={x:Type cs:VolumeControl}....
<ControlTemplate x:Key="Vertical" TargetType={x:Type cs:VolumeControl}...

then create a style and use that to switch the templates through a trigger

<Style TargetType={x:Type cs:VolumeControl}>
<Style.Triggers>
   <Trigger Property="Orientation" Value="Horizontal">
      <Setter Property="Template" Value={StaticResource Horizontal}" />
   </Trigger>
   <Trigger Property="Orientation" Value="Vertical">
      <Setter Property="Template" Value={StaticResource Vertical}" />
   </Trigger>
</Style.Triggers>
</Style>

works like a charm for me :)

0
votes

Having styles nest like that is probably not going to work out. You could possibly use a ContentControl, something like this:

<Style TargetType="{x:Type cs:VolumeControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type cs:VolumeControl}">
                <ContentControl>
                    <ContentControl.Style>
                        <Style TargetType="{x:Type ContentControl}">
                            <Setter Property="ContentTemplate">
                                <Setter.Value>
                                    <!-- Horizontal Template Here -->
                                </Setter.Value>
                            </Setter>
                            <Style.Triggers>
                                <DataTrigger Binding="{TemplateBinding Orientation}" Value="Vertical">
                                    <Setter Property="ContentTemplate">
                                        <Setter.Value>
                                            <!-- Vertical Template Here -->
                                        </Setter.Value>
                                    </Setter>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </ContentControl.Style>
                </ContentControl>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

I however am not sure if this works and whether it is actually a good idea.