C# 将自定义依赖属性绑定到自定义 WPF 样式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/973372/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:35:17  来源:igfitidea点击:

Binding custom dependency property to custom WPF style

c#wpfxamlstylescontroltemplate

提问by Alastair Pitts

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.

我有这个 XAML 代码,它为我提供了标题中的进度条。这是自定义样式。

<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.

我不确定如何将此依赖属性进度绑定到样式中 ProgressBar 中的进度值。

Any help would be appreciated.

任何帮助,将不胜感激。

采纳答案by rmoore

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

在样式中,我们可以使用带有 RelativeSource 的标准 Binding 来设置属性。

<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.

然后,在窗口中我们只需添加 Progress="50" 或其他地方的绑定。

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

您还需要将 Button 的背景设置为透明,或更改布局的某种方式,以便看到它。