views:

3187

answers:

1

I have an issue when designing a inherited Expander. My intention is to have a progress bar behind the toggle button and text in the default Expander header.

I have this XAML code which gives me the progress bar in the header. It is a custom style.

<Style x:Key="CurrentScanExpanderStyle" TargetType="{x:Type local:ProgressExpander}">
     <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
     <Setter Property="Background" Value="Transparent"/>
     <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
     <Setter Property="VerticalContentAlignment" Value="Stretch"/>
     <Setter Property="BorderBrush" Value="Transparent"/>
        <Setter Property="BorderThickness" Value="1"/>
     <Setter Property="Template">
      <Setter.Value>
       <ControlTemplate TargetType="{x:Type local:ProgressExpander}">
        <Border SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="3">
         <DockPanel>
                            <Grid DockPanel.Dock="Top">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*"/>
                                </Grid.ColumnDefinitions>
                                <ProgressBar Name="ProgressBar"/>
                                <ToggleButton FontFamily="{TemplateBinding FontFamily}" FontSize="{TemplateBinding FontSize}" FontStretch="{TemplateBinding FontStretch}" FontStyle="{TemplateBinding FontStyle}" FontWeight="{TemplateBinding FontWeight}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" FocusVisualStyle="{StaticResource ExpanderHeaderFocusVisual}" Margin="1" MinHeight="0" MinWidth="0" x:Name="HeaderSite" Style="{StaticResource ExpanderDownHeaderStyle}" IsChecked="{Binding Path=IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Content="{TemplateBinding Header}" ContentTemplate="{TemplateBinding HeaderTemplate}" ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}"/>
                            </Grid>
          <ContentPresenter Focusable="false" Visibility="Collapsed" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" x:Name="ExpandSite" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" DockPanel.Dock="Bottom"/>
                        </DockPanel>
        </Border>
        <ControlTemplate.Triggers>
         <!-- Triggers haven't changed from the default -->
        </ControlTemplate.Triggers>
       </ControlTemplate>
      </Setter.Value>
     </Setter>
    </Style>

this works fine but I am having trouble binding my custom dependency property which controls the progress percentage.

    public class ProgressExpander : Expander
{
    static ProgressExpander()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(ProgressExpander), new FrameworkPropertyMetadata(typeof(ProgressExpander)));
    }       



    public int Progress
    {
        get { return (int)GetValue(ProgressProperty); }
        set { SetValue(ProgressProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Progress.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ProgressProperty =
        DependencyProperty.Register("Progress", typeof(int), typeof(ProgressExpander), new UIPropertyMetadata(0));


}

This is the code inside of the window:

            <local:ProgressExpander Grid.Row="1" Header="Current Scan" ExpandDirection="Down" x:Name="currentScanExpander" Style="{DynamicResource CurrentScanExpanderStyle}">
                <Canvas Background="SkyBlue" 
                        Name="currentScanCanvas"
                        Height="{Binding ElementName=currentScanExpander, Path=ActualWidth}"
                        />
            </local:ProgressExpander>

I'm not sure how to bind this dependency property progress to the progress value in the ProgressBar within the style.

Any help would be appreciated.

+3  A: 

In the style, we can use a standard Binding with a RelativeSource to set up the property.

<ProgressBar Name="ProgressBar"
    Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Progress}"
    Minimum="0"
    Maximum="100" />

Then, in the window we just add Progress="50" or a binding to somewhere else.

You will also need to set the Button's background to transparent, or change some manner of the layout, in order to see it.

rmoore
Could probably use a TemplateBinding instead; less typing, plus that's what TemplateBinding is for. http://msdn.microsoft.com/en-us/library/ms742882.aspx
Joe White
There's something wrong with the code as/is that is preventing it from using TemplateBindings, which is why I set it up using the stronger Binding.
rmoore
This worked a treat! Iwas having a bunch of problems with the templatebindings... must have been an inheritance thing.Thanks a bundle. =D
Alastair Pitts