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

C# WPF按钮模板中的矢量图像不总是显示,c#,wpf,xaml,dependency-properties,controltemplate,C#,Wpf,Xaml,Dependency Properties,Controltemplate,我有一个WPF应用程序,它有两个按钮,上面没有文本,只有一个基于向量的图像(使用路径对象),ControlTemplate如下所示: <ControlTemplate x:Key="IconButtonContentTemplate" TargetType="{x:Type ButtonBase}"> <Grid Background="{Binding Background, RelativeSource={RelativeSource AncestorType={x

我有一个WPF应用程序,它有两个按钮,上面没有文本,只有一个基于向量的图像(使用路径对象),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>
知道我做错了什么吗

我不确定是什么原因造成的

在某些点上,
ActualWidth
ActualHeight
(在任何控件上)的值实际上为零,并且这些属性是只读类型依赖属性。当控件
加载
测量
排列
,或
渲染
时会发生这种情况

按照

因为
ActualWidth
是一个计算值,所以您应该知道 作为一个整体,可能会有多个或增量报告的更改 布局系统的各种操作的结果。布局系统 可能正在计算子图元所需的测量空间, 父元素的约束,等等

问题是有什么东西在抖动你的按钮,导致调整大小,而你抓住了一个零值就中奖了


作为一个尝试的过程,我提供了一个关于以两种不同方式容纳矢量图像的答案,我使用的示例在一个可调整大小的窗口中有3个矢量,据我所知,它们除了重新绘制之外,没有闪烁。但是我将高度/宽度设置为
拉伸

也许可以改变向量的保持方式?

您应该:

1) 删除填充颜色上的数据绑定,以确定是否仍然可以重新生成问题

如果你不能,那么换个角度试试:

2) 移除路径上的数据绑定(使用恒定路径进行测试)并使用填充颜色上的数据绑定进行测试

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

如果你能在1)或2)中重新产生问题,你现在至少知道问题的根源。这同样适用于3),但更为复杂,因为3)意味着两个数据绑定以某种方式相互影响

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

5) 我还将尝试在按钮的背景上布局路径,看看这是否能更好地解决您的问题-请参阅我在本文中的最后一条评论:

你真的需要发布一个小的演示应用程序来获得确定的答案,否则,我恐怕无法说出确切的来源,因为只有显示的片段

你正在将模板元素的所需维度绑定到模板化父元素的最终维度;这将创建一个循环依赖项。不要那样做

模板控件的大小(例如,
按钮
)取决于其模板内容的所需大小(例如,
路径
)。如果您使内容的大小依赖于模板化父级的大小,那么您只是自找麻烦

如果非要我猜的话,您可能会陷入布局循环中,其中一个布局更新会在下一个滴答声中触发另一个布局更新。由于布局更新的计划方式,这些并不总是显而易见的(也许通过查看CPU使用情况除外)。我以前见过这种情况,例如,当“排列”过程使“度量”过程的结果无效时。可见的影响可能是相当不可预测的:有时事情似乎运作良好,直到他们不


去掉
路径上的
宽度
高度
绑定
,并将水平和垂直对齐设置为
拉伸

调试绑定:连接一些可见性/父级更改事件并将其写入控制台。尝试使用位图图像执行类似操作。连接到AppDomain.CurrentDomain.FirstChanceException,查看是否有可疑内容。。。使用可设置样式的触发器,当用户要求使用暗模式时,硬编码的颜色看起来很奇怪。请使用visual Studio Live tree或Snoop等外部工具检查视觉树。验证所有元素都在您期望的位置,并且所有属性都是您期望的。然后你可能会发现罪魁祸首根据你的统计数据,至少有2个按钮会出现问题,但即使在多次执行后,问题也不会发生。无法重现,你是否可以发布一个带有该问题的演示项目?此外,如果您可以发布
IconButtonStyle
的代码,这将非常有用,因为它可能有一些我不知道的触发器。请尝试显式设置
Path
的宽度和高度(无任何绑定),并查看是否再次发生这种情况?“捕获零值”这意味着完成布局过程后,ActualWidth或ActualHeight的最终值将为零,这毫无意义。不过,宽度和高度绑定是完全冗余的。网格已调整其路径子级的大小。水平对齐和垂直对齐也是多余的。最后,Background和Fill应该使用TemplateBindings。次要的挑剔:
ActualWidth/Height
是依赖属性,但它们是只读依赖属性,不能显式设置(这些值是从
renderize
中提取的)。就属性从DP更改通知机制中受益而言,这是非常重要的。@MikeStrobel相应地调整了文本。ThxStretch是路径对齐属性的默认值。不需要设置它们。@Clemens True,但是如果我们真的想“正确”,那么
路径上的
[H/V]Alignment
属性可能应该绑定到模板化父级的相应
[H/V]ContentAlignment
属性。
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);
    }
}