WPF XAML资源对象仅显示一次 三个按钮仅最后一个显示ViewBox图标
问题根本原因
WPF中所有FrameworkElement派生类(包括Viewbox)在可视化树中仅能拥有一个父元素。你在资源字典中定义的IconTrash默认开启了x:Shared="True"特性,所有按钮引用的都是同一个Viewbox实例。当该实例被依次赋值给三个按钮的内容时,每一次赋值都会自动将Viewbox从前一个按钮的可视化树中移除,因此最终仅最后一个按钮能显示图标。
解决方案
方案1(改动最小)
给IconTrash资源添加x:Shared="False"属性,每次引用资源时都会生成新的Viewbox实例,避免父元素冲突:
<Viewbox x:Key="IconTrash" x:Shared="False"> <!-- 原有内容不变 --> </Viewbox>
方案2(性能更优,推荐)
不要直接将UI元素作为资源存储,改为存储路径几何数据,在控件模板中复用:
- 替换原有
IconTrash资源为几何资源:
<Geometry x:Key="TrashGeometry">M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z</Geometry>
- 修改按钮控件模板,直接在模板内构造图标结构:
<ControlTemplate TargetType="Button"> <Border Background="{TemplateBinding Background}"> <Viewbox x:Name="IconControl"> <Canvas Width="24" Height="24"> <Path Data="{StaticResource TrashGeometry}" Fill="{TemplateBinding Foreground}" /> </Canvas> </Viewbox> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="IconControl" Property="Opacity" Value="0.5" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate>
该方案无需创建多个Viewbox实例,资源占用更低,也不会出现父元素冲突问题。
内容的提问来源于stack exchange,提问作者Jason Grant
相关产品推荐
相关产品推荐

