【发布时间】:2016-04-21 16:08:39
【问题描述】:
我有以下(工作)代码:
<StackPanel>
<Menu>
<Menu.Resources>
<Style TargetType="{x:Type MenuItem}" x:Key="MenuItemStyle">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="LightGray" />
<Setter Property="Foreground" Value="LightSlateGray" />
</Trigger>
<Trigger Property="IsEnabled" Value="True">
<Setter Property="Background" Value="LightGray" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type MenuItem}" x:Key="DeleteMenuStyle" BasedOn="{StaticResource MenuItemStyle}">
<Setter Property="Icon">
<Setter.Value>
<ContentControl Style="{StaticResource CrossIconScalable}"
Width="15"
Height="15"/>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type MenuItem}" x:Key="SaveMenuStyle" BasedOn="{StaticResource MenuItemStyle}">
<Setter Property="Icon">
<Setter.Value>
<ContentControl Style="{StaticResource SaveButtonScalable}"
Width="15"
Height="15"/>
</Setter.Value>
</Setter>
</Style>
</Menu.Resources>
<MenuItem>
<MenuItem.Header>
<!-- ... -->
</MenuItem.Header>
<MenuItem Name="SaveImageMenu" Header="{Binding MenuItemSaveTxt}"
Click="SaveImageMenu_OnClick" Style="{StaticResource SaveMenuStyle}" />
<MenuItem Name="DeleteViewMenu" Header="{Binding MenuItemCancTxt}"
Click="DeleteViewMenu_OnClick" Style="{StaticResource DeleteMenuStyle}" />
</MenuItem>
</Menu>
</StackPanel>
<!-- StaticResources definition -->
<Style TargetType="ContentControl" x:Key="SaveButtonScalable">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<Viewbox Stretch="Uniform">
<Canvas Name="Capa_1" Width="32" Height="32">
<Canvas.RenderTransform>
<TranslateTransform X="0" Y="0" />
</Canvas.RenderTransform>
<Canvas.Resources />
<Canvas Name="g3">
<Path Name="path5" Fill="{TemplateBinding Foreground}">
<Path.Data>
<PathGeometry Figures="M26 0h-2v13H8V0H0v32h32V6L26 0z M28 30H4V16h24V30z"
FillRule="NonZero" />
</Path.Data>
</Path>
<Rectangle Canvas.Left="6" Canvas.Top="18" Width="20" Height="2" Name="rect7"
Fill="{TemplateBinding Foreground}" />
<Rectangle Canvas.Left="6" Canvas.Top="22" Width="20" Height="2" Name="rect9"
Fill="{TemplateBinding Foreground}" />
<Rectangle Canvas.Left="6" Canvas.Top="26" Width="20" Height="2" Name="rect11"
Fill="{TemplateBinding Foreground}" />
<Rectangle Canvas.Left="18" Canvas.Top="2" Width="4" Height="9" Name="rect13"
Fill="{TemplateBinding Foreground}" />
</Canvas>
</Canvas>
</Viewbox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="ContentControl" x:Key="CrossIconScalable">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<Viewbox Stretch="Uniform">
<Canvas Name="svg2" Width="32" Height="32">
<Canvas.RenderTransform>
<TranslateTransform X="0" Y="0"/>
</Canvas.RenderTransform>
<Canvas.Resources/>
<Path Name="path4">
<Path.Data>
<PathGeometry Figures="m0 0h32v32h-32z" FillRule="NonZero"/>
</Path.Data>
</Path>
<Path Name="path6" Fill="{TemplateBinding Foreground}">
<Path.Data>
<PathGeometry Figures="m2 26 4 4 10-10 10 10 4-4-10-10 10-10-4-4-10 10-10-10-4 4 10 10z" FillRule="NonZero"/>
</Path.Data>
</Path>
</Canvas>
</Viewbox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
如您所见,这里有一些代码重复:
- 两个声明的
Style元素(DeleteMenuStyle和SaveMenuStyle)除了用于每个ContenControl的<Style>之外是相同的。 -
SaveButtonScalable和CrossIconScalable样式对于父标记是相同的,但它们在内部的<Canvas>标记中有所不同。
我想重构它以创建更紧凑且没有任何重复的代码。
我该怎么做?
【问题讨论】:
-
代码的大量重复在哪里?你能解释一下吗?
-
在这两种样式中,除了静态资源之外的所有内容都是重复的。我想将两个声明合并为一个
-
CrossIconScalable和SaveButtonScalable样式中有什么?鉴于您正在使用ControlControl,您是否可以为每种类型的菜单项声明DataTemplate,将适当的视图模型对象绑定为上下文?如果没有一个好的minimal reproducible example,就很难理解你的选择是什么,即如何适应你的代码的其余部分,以及你可能有哪些选项来清理它们。 -
@PeterDuniho 抱歉信息不足,现在我为我的问题添加了更多细节:)
-
抱歉,这仍然不是一个好的minimal reproducible example。它更详细,但仍然不完整。
Canvas中的内容很重要,因为真正做到这一点的最佳方法是为内容声明DataTemplate,然后将MenuItem.DataContext设置为内容,而不是弄乱Style。根据您代码中的“SVG”,我怀疑您有PathGeometry或类似名称,它可以是模板的数据类型,然后将该几何图形应用于模板中的图形。我可以发布一个示例作为答案,但没有具体细节,我不能确定它会有所帮助。
标签: c# wpf xaml refactoring reusability