WPF 按钮模板中的矢量图像并不总是显示

Vector Image in WPF Button Template Not Always Showing

我的 WPF 应用程序有几个按钮,上面没有文本,只有一个基于矢量的图像(使用 Path 对象),ControlTemplate 如下所示:

<ControlTemplate x:Key="IconButtonContentTemplate" TargetType="{x:Type ButtonBase}">
    <Grid Background="{Binding Background, RelativeSource={RelativeSource AncestorType={x:Type ButtonBase}, Mode=FindAncestor}}">
        <Path HorizontalAlignment="Center" VerticalAlignment="Center" 
            Width="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type ButtonBase}, Mode=FindAncestor}}" 
            Height="{Binding ActualHeight, RelativeSource={RelativeSource AncestorType={x:Type ButtonBase}, Mode=FindAncestor}}"   
            Data="{Binding (components:ImageButtonAttachedProperties.ImagePathData), RelativeSource={RelativeSource AncestorType={x:Type ButtonBase}, Mode=FindAncestor}}"
            Stretch="Uniform" Fill="{Binding Foreground, RelativeSource={RelativeSource AncestorType={x:Type ButtonBase}, Mode=FindAncestor}}" />
    </Grid>

    <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Foreground" Value="LightGray" />
        </Trigger>
        <Trigger Property="IsPressed" Value="True">
            <Setter Property="Foreground" Value="LightGray" />
        </Trigger>
        <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Foreground" Value="Gray" />
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate> 


<Style TargetType="{x:Type Button}" x:Key="ClockButtonStyle" BasedOn="{StaticResource IconButtonStyle}">
    <Setter Property="Template" Value="{StaticResource IconButtonContentTemplate}" />
    <Setter Property="Foreground" Value="White" />
    <Setter Property="components:ImageButtonAttachedProperties.ImagePathData" Value="M69.349,65.092C68.714,65.092,68.072,64.925,67.487,64.577L46.294,51.946 46.294,21.239C46.294,19.227 47.925,17.595 49.938,17.595 51.949,17.595 53.581,19.227 53.581,21.239L53.581,47.807 71.217,58.317C72.945,59.348 73.512,61.585 72.483,63.312 71.799,64.457 70.589,65.092 69.349,65.092z M49.938,3.877C24.573,3.877 3.938,24.513 3.938,49.877 3.938,75.241 24.573,95.877 49.938,95.877 75.302,95.877 95.938,75.241 95.938,49.877 95.938,24.513 75.302,3.877 49.938,3.877z M52.876,88.467C52.882,88.395 52.897,88.324 52.897,88.25 52.897,86.615 51.572,85.29 49.937,85.29 48.302,85.29 46.977,86.615 46.977,88.25 46.977,88.324 46.994,88.395 46.999,88.467 27.994,87.032 12.783,71.822 11.349,52.817 11.423,52.822 11.492,52.838 11.567,52.838 13.202,52.838 14.527,51.513 14.527,49.878 14.527,48.243 13.201,46.918 11.567,46.918 11.492,46.918 11.422,46.935 11.349,46.94 12.783,27.933 27.994,12.722 47,11.287 46.995,11.36 46.978,11.43 46.978,11.504 46.978,13.139 48.304,14.464 49.938,14.464 51.572,14.464 52.897,13.138 52.897,11.504 52.897,11.429 52.881,11.36 52.876,11.287 71.882,12.722 87.093,27.932 88.528,46.938 88.455,46.933 88.385,46.916 88.311,46.916 86.676,46.916 85.35,48.242 85.35,49.876 85.35,51.51 86.676,52.836 88.311,52.836 88.385,52.836 88.455,52.82 88.528,52.815 87.094,71.822 71.883,87.032 52.876,88.467z" />
</Style>

我的问题是在极少数情况下按钮图像不显示(99% 的时间显示)。该按钮仍可单击,但其上的图像未显示。 我不确定是什么原因造成的。矢量图像上的数据绑定?还是填充颜色上的数据绑定?

ImageButtonAttachedProperties.ImagePathDataSystem.Windows.Media.Geometry对象,它描述了矢量图像。

public static class ImageButtonAttachedProperties
{
    public static readonly DependencyProperty ImagePathDataProperty =
        DependencyProperty.RegisterAttached("ImagePathData", typeof(Geometry), typeof(ImageButtonAttachedProperties), new UIPropertyMetadata(null));

    public static Geometry GetImagePathData(DependencyObject obj)
    {
        return (Geometry)obj.GetValue(ImagePathDataProperty);
    }

    public static void SetImagePathData(DependencyObject obj, Geometry value)
    {
        obj.SetValue(ImagePathDataProperty, value);
    }
}

知道我做错了什么吗?

I'm not sure what's causing this.

在某些时候,ActualWidthActualHeight(在任何控件上)的值实际上为零,并且这些属性是只读类型依赖属性。当控件为 LoadedMeasuredArrangedRendered.

时会发生这种情况

根据 FrameworkElement.ActualWidth 属性

Because ActualWidth is a calculated value, you should be aware that there could be multiple or incremental reported changes to it as a result of various operations by the layout system. The layout system may be calculating required measure space for child elements, constraints by the parent element, and so on.

问题是有些东西 操纵 你的按钮并导致调整大小,你 中了彩票 得到了零值。


作为尝试的过程,我提供了一个关于以两种不同方式容纳矢量图像 Best way to use a vector image in WPF 的答案,我使用的示例在可调整大小的 window 中有 3 个矢量,并且据我所知,他们 flash 除了重画。但是我将 height/width 设置为 stretch

也许改变向量的保存方式?

你应该:

1) 删除填充颜色上的数据绑定以确定您是否仍然可以重现问题。

我不行,反过来试试:

2) 删除 Path 上的数据绑定(使用常量 Path 进行测试)并使用填充颜色上的数据绑定进行测试。

如果 1) 和 2) 无法重现您的问题,请尝试: 3) 在填充颜色和路径上的数据绑定上使用常量值

如果您能够重现 1) 或 2) 中的问题,您现在至少知道问题的根源了。 3) 也是如此,但它更复杂,因为 3) 意味着两个数据绑定以某种方式相互影响 ...

4) 也有可能您的问题在主题定义中隐藏得更深 - 因此关闭自定义主题并仅使用泛型主题也是一种测试方法,以便了解问题的根源。

5) 我也会尝试在按钮的背景上布置路径,看看这是否能更好地解决您的问题 - 请参阅我在此 post 中的最后评论: Image fill the space on the button in WPF

你真的需要 post 一个小的演示应用程序来获得确定性的答案,否则,恐怕仅根据显示的片段无法说出确切的来源

您将模板元素的期望 维度绑定到模板化父元素的最终 维度;这会产生循环依赖。不要那样做。

模板化控件(例如,您的 Button)的大小取决于其模板内容(例如,您的 Path)的所需大小。如果您使内容的大小取决于模板化父级的大小,那您只是在自找麻烦。

如果我不得不猜测,您可能陷入了布局循环,其中一个布局更新会触发另一个布局更新在下一次更新时发生。由于安排布局更新的方式,这些并不总是很明显(除了可能通过查看 CPU 用法)。我以前见过这种情况,例如,当 'Arrange' 遍使 'Measure' 遍的结果无效时。可见的效果可能相当难以预测:有时事情 看起来 工作正常,直到它们不工作。

删除 Path 上的 WidthHeight 绑定,并将水平和垂直对齐设置为 Stretch