简体   繁体   English

在“扩展器”按钮周围设置边框会略微调整其大小

[英]Setting a border around an Expander button resizes it slightly

I am making an Expander style, and I noticed that when the border around the Expander 's ToggleButton goes from 0 to a non-zero value - "0,0,1,1", in this case - it is resized slightly, to shrink inside the border: 我正在制作一个Expander样式,我注意到,在ExpanderToggleButton周围的边框从0变为非零值(在这种情况下为“ 0,0,1,1”)时,它的大小会略微调整为在边界内缩小:

扩展

Not exactly app-breaking... But annoying that I can't fix it. 并非完全破坏应用程序...但是令人讨厌的是我无法修复它。 How can I circumvent this? 我该如何规避? I need the Border in the ToggleButton 's style to be 0 when the Expander is collapsed (since Expander has its own border that would make it look like a doubly-thick border) and non-zero when expanded (since I want the button to be separated by a border from the rest of the content). Expander ToggleButton我需要ToggleButton样式的Border为0(因为Expander具有自己的边框,这会使它看起来像是双倍的边框),而在展开时则为非零(因为我希望按钮能够与其他内容之间用边框隔开)。

ToggleButton style: ToggleButton样式:

<Style x:Key="ExpanderRightHeaderStyle" TargetType="{x:Type ToggleButton}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ToggleButton}">
                <Border x:Name="Bd" Background="{StaticResource MutedColorBrush}" BorderBrush="{StaticResource Expander.Border}" Padding="{TemplateBinding Padding}" CornerRadius="0" Height="22" Width="22">
                    <Grid Background="Transparent" SnapsToDevicePixels="False" Margin="0">
                        <ui:ColorableImage x:Name="img" Margin="0" Padding="2" Background="{StaticResource MutedColorBrush}" Color="Black"  Height="{Binding Path=Height, RelativeSource={RelativeSource AncestorType={x:Type Border}}}" Width="{Binding Path=Width, RelativeSource={RelativeSource AncestorType={x:Type Border}}}" Source="Assets/Images/filter.png" HorizontalAlignment="Center" VerticalAlignment="Center" SnapsToDevicePixels="false"/>
                        <ContentPresenter HorizontalAlignment="Center" Margin="12,0,12,0" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Top"/>
                    </Grid>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsChecked" Value="true">
                        <Setter Property="BorderThickness" TargetName="Bd" Value="0,0,1,1" />
                    </Trigger>
                    <Trigger Property="IsMouseOver" Value="true">
                        <Setter Property="Background" TargetName="Bd" Value="{StaticResource MainColorBrush}"/>
                        <Setter Property="Background" TargetName="img" Value="{StaticResource MainColorBrush}"/>
                    </Trigger>
                    <Trigger Property="IsPressed" Value="true">
                        <Setter Property="Color" TargetName="img" Value="White"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Expander style: Expander样式:

<Style TargetType="{x:Type Expander}">
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
    <Setter Property="Background" Value="#F0F0F0"/>
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    <Setter Property="VerticalContentAlignment" Value="Stretch"/>
    <Setter Property="BorderBrush" Value="{StaticResource Expander.Border}"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Expander}">
                <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="0" SnapsToDevicePixels="true">
                    <DockPanel>
                        <ToggleButton x:Name="HeaderSite" ContentTemplate="{TemplateBinding HeaderTemplate}" ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}" Content="{TemplateBinding Header}" DockPanel.Dock="Top" Foreground="{TemplateBinding Foreground}" FontWeight="{TemplateBinding FontWeight}" FocusVisualStyle="{StaticResource ExpanderHeaderFocusVisual}" FontStyle="{TemplateBinding FontStyle}" FontStretch="{TemplateBinding FontStretch}" FontSize="{TemplateBinding FontSize}" FontFamily="{TemplateBinding FontFamily}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Margin="0" MinWidth="0" MinHeight="0" Padding="0" Style="{StaticResource ExpanderDownHeaderStyle}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" VerticalAlignment="Top" Width="Auto" Height="Auto"/>
                        <ContentPresenter x:Name="ExpandSite" DockPanel.Dock="Bottom" Focusable="false" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="5,0,5,10" Visibility="Collapsed" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </DockPanel>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsExpanded" Value="true">
                        <Setter Property="Visibility" TargetName="ExpandSite" Value="Visible"/>
                        <Setter Property="Height" Value="Auto"/>
                        <Setter Property="Height" TargetName="ExpandSite" Value="Auto"/>
                    </Trigger>
                    <Trigger Property="ExpandDirection" Value="Right">
                        <Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Right"/>
                        <Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Left"/>
                        <Setter Property="Style" TargetName="HeaderSite" Value="{StaticResource ExpanderRightHeaderStyle}"/>
                    </Trigger>
                    <Trigger Property="ExpandDirection" Value="Up">
                        <Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Top"/>
                        <Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Bottom"/>
                        <Setter Property="Style" TargetName="HeaderSite" Value="{StaticResource ExpanderUpHeaderStyle}"/>
                    </Trigger>
                    <Trigger Property="ExpandDirection" Value="Left">
                        <Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Left"/>
                        <Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Right"/>
                        <Setter Property="Style" TargetName="HeaderSite" Value="{StaticResource ExpanderLeftHeaderStyle}"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Possibly related - the ColorableImage control: 可能相关ColorableImage控件:

ColorableImage.xaml (x:Name="This"): ColorableImage.xaml(x:Name =“ This”):

<Grid>
    <Image x:Name="originalImage"  Visibility="Hidden"  Stretch="{Binding ElementName=This, Path=Stretch}" Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualHeight}" Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualWidth}"/>
    <Image x:Name="displayedImage" Visibility="Visible" Stretch="{Binding ElementName=This, Path=Stretch}" Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualHeight}" Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualWidth}" />
</Grid>

ColorableImage.xaml.cs: ColorableImage.xaml.cs:

public partial class ColorableImage : UserControl
{
    // This is so that SourcePropertyChanged will not execute when ColorPropertyChanged does. ColorPropertyChanged changes Source,
    // so SourcePropertyChanged is called in turn. This will change originalImage to the newly colored Source, which is incorrect.
    // "Wrapping" the statement that changes the binding in ColorPropertyChanged with this boolean and making it a condition in 
    // SourcePropertyChanged makes SourcePropertyChanged executre only when Source is directly changed, whether through C# or XAML.
    private static bool changedByColor = false;

    public ColorableImage()
    {
        InitializeComponent();
    }

    public static readonly DependencyProperty ColorProperty = DependencyProperty.Register("Color", typeof(Color), typeof(ColorableImage), new FrameworkPropertyMetadata(ColorPropertyChanged));
    public Color Color
    {
        get { return (Color)GetValue(ColorProperty); }
        set { SetValue(ColorProperty, value); }
    }

    public static readonly DependencyProperty SourceProperty = DependencyProperty.Register("Source", typeof(ImageSource), typeof(ColorableImage), new FrameworkPropertyMetadata(SourcePropertyChanged));
    public ImageSource Source
    {
        get { return (ImageSource)GetValue(SourceProperty); }
        set { SetValue(SourceProperty, value); }
    }

    public static readonly DependencyProperty StretchProperty = DependencyProperty.Register("Stretch", typeof(Stretch), typeof(ColorableImage), new FrameworkPropertyMetadata(Stretch.Uniform));
    public Stretch Stretch
    {
        get { return (Stretch)GetValue(StretchProperty); }
        set
        {
            SetValue(StretchProperty, value);
            this.originalImage.Stretch = value;
            this.displayedImage.Stretch = value;
        }
    }

    private static void ColorPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        ColorableImage cimg = (ColorableImage)sender;

        Binding binding = new Binding("Source")
        {
            ElementName = "originalImage",
            Converter = new HighlightImageConverter(),
            ConverterParameter = cimg.Color,
            Mode = BindingMode.OneWay
        };

        changedByColor = true;
        cimg.displayedImage.SetBinding(Image.SourceProperty, binding);
        changedByColor = false;
    }

    private static void SourcePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        if (!changedByColor)
        {
            ColorableImage cimg = (ColorableImage)sender;

            cimg.originalImage.Source = cimg.Source;
            cimg.displayedImage.Source = cimg.Source;
            // Note: #00000000 is the value for the "null color"
            if (cimg.Color != null && !cimg.Color.ToString().Equals("#00000000"))
            {
                // Color the new image (this is necessary if the user sets the source after the color; the color would be lost, otherwise)
                ColorPropertyChanged(sender, e);
            }
        }
    }
}

You can probably avoid that problem by setting the BorderBrush to transparent, instead of setting the BorderThickness to 0. 您可以通过将BorderBrush设置为透明而不是将BorderThickness设置为0来避免该问题。

You might possibly have to add an extra container... 您可能必须添加一个额外的容器...
I don't feel like testing this, since the question is old and @Sheridan wrote that he had trouble making it work. 我不喜欢测试此问题,因为问题很旧, @ Sheridan写道他无法使其正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM