首页 > 解决方案 > 在父样式 WPF 中设置属性值

问题描述

我有以下Style用于自定义控件的 WPF

<Style TargetType="{x:Type local:TransportControl}">
    <Setter Property="MinorTickBrush" Value="{DynamicResource BlackBrush}"/>
    <Setter Property="MajorTickBrush" Value="{DynamicResource BlackBrush}"/>
    <Setter Property="IndicatorBrush" Value="{DynamicResource BlckBrush}"/>
    <Setter Property="ProgressBorderBrush" Value="{DynamicResource BlackBrush}"/>
    <Setter Property="ProgressBrush" Value="{DynamicResource HighlightBrush}"/>
    <Setter Property="IndicatorSize" Value="16"/>
    <Setter Property="IndicatorBrush" Value="{DynamicResource BlackBrush}"/>
    <Setter Property="IndicatorGlow" Value="True"/>
    <Setter Property="IndicatorGlowBrush" Value="GhostWhite"/>
    <Setter Property="FontFamily" Value="Segoe UI"/>

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:TransportControl}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        Padding="{Binding Path=DataContext.IndicatorSize, 
                            RelativeSource={RelativeSource AncestorType={x:Type local:TransportControl}}, 
                            Converter={StaticResource ValueToHorizontalPaddingConverter}}"
                        Margin="4,2">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="20"/>
                            <RowDefinition Height="*"/>
                        </Grid.RowDefinitions>
                        <Canvas Name="PART_TimelineCanvas" Grid.Row="0" Height="20" ClipToBounds="False"/>
                        <Canvas Name="PART_ProgressCanvas" Grid.Row="1" ClipToBounds="False"/>
                        <Canvas Name="PART_IndicatorCanvas" 
                                  Grid.Row="0" 
                                  Grid.RowSpan="2" 
                                  ClipToBounds="False" 
                                  Panel.ZIndex="2"/>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

IValueConverter作为

public class ValueToHorizontalPaddingConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object format, CultureInfo culture)
    {
        double padding = System.Convert.ToDouble(value);
        return new Thickness(padding, 0, padding, 0);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

我正在尝试设置控件的填充,以便我的指示器可以正确居中。我希望控件的填充是IndicatorSize父样式中设置的一半。目前,我只是想让它成为IndicatorSize,但我尝试的绑定没有按预期工作。

Padding="{Binding Path=DataContext.IndicatorSize, 
    RelativeSource={RelativeSource AncestorType={x:Type local:TransportControl}}, 
    Converter={StaticResource ValueToHorizontalPaddingConverter}}" 

我究竟做错了什么?

谢谢你的时间。

标签: wpfxamlmvvm

解决方案


您可以使用 TemplateBinding 来做到这一点:

Padding="{TemplateBinding IndicatorSize, Converter={StaticResource ValueToHorizontalPaddingConverter}}"

使指示器居中的另一种方法是为边框命名,在自定义控件的 OnApplyTemplate(..) 方法中获取对它的引用,并在 IndicatorSize 属性更改时在 C# 中设置其填充。这样您就不需要绑定和转换器。


推荐阅读