我的应用程序(使用MahApps.Metro
)具有许多<Button>
的{{1}}元素,除了Content
本身的不同属性以及我想通过<Button>
上的新属性(附加属性?)来参数化单个Button.Content
子元素属性。
我有大约20个此XAML实例用于按钮:
<Button>
我已经通过将常量属性移动到派生样式来缩小了它:
<Button
Style="{StaticResource MetroCircleButtonStyle}"
Margin="0,-4,-4,2"
DockPanel.Dock="Right"
Width="32"
Height="32"
Name="targetSystemAutoconfigureButton"
ToolTip="{x:Static me:Resources.Settings_AutoconfigureTargetSystem}"
Command="{Binding AutoconfigureTargetSystemCommand}"
>
<Button.Content>
<Rectangle Fill="{Binding Foreground, ElementName=targetSystemAutoconfigureButton}" Width="12" Height="12">
<Rectangle.OpacityMask>
<DrawingBrush Drawing="{StaticResource appbar_magnify}" Stretch="Uniform" />
</Rectangle.OpacityMask>
</Rectangle>
</Button.Content>
</Button>
但是我只想拥有这个:
<!-- In a <ResourceDictionary> located elsewhere -->
<Style x:Key="inputSplitIconButton" TargetType="Button" BasedOn="{StaticResource MetroCircleButtonStyle}">
<Setter Property="Margin" Value="0,-4,-4,2" />
<Setter Property="DockPanel.Dock" Value="Right" />
<Setter Property="Width" Value="32" />
<Setter Property="Height" Value="32" />
</Style>
<!-- Button XAML is now: -->
<Button
Style="{StaticResource inputSplitIconButton}"
Name="targetSystemAutoconfigureButton"
ToolTip="{x:Static me:Resources.Settings_AutoconfigureTargetSystem}"
Command="{Binding AutoconfigureTargetSystemCommand}"
>
<Button.Content>
<Rectangle Fill="{Binding Foreground, ElementName=targetSystemAutoconfigureButton}" Width="12" Height="12">
<Rectangle.OpacityMask>
<DrawingBrush Drawing="{StaticResource appbar_magnify}" Stretch="Uniform" />
</Rectangle.OpacityMask>
</Rectangle>
</Button.Content>
</Button>
WPF的一个问题是,至少有三种不同的方法可以达到相同的最终结果,但是我不知道WPF到底如何选择最好的。我知道我的选择是:
<Button
Style="{StaticResource inputSplitIconButton}"
Name="targetSystemAutoconfigureButton"
ToolTip="{x:Static me:Resources.Settings_AutoconfigureTargetSystem}"
Command="{Binding AutoconfigureTargetSystemCommand}"
ImageMask="{StaticResource appbar_magnify}" <--- this property
/>
中设置Content
属性。
<Style x:Key="inputSplitIconButton">
属性?Drawing=""
中设置DataTemplate
属性,并为<Style x:Key="inputSplitIconButton">
属性使用DataContext
绑定,并将其作为新的Drawing=""
传入按钮实例
DataContext
的过程中,存在不同的主题变化:
DataTemplate
DataTemplate
属性来存储Tag
名称。StaticResource
并在那里添加我自己的属性,并在代码中创建内容结构。
Button
”),该属性在元素上设置时会自动添加me:Drawing=""
等子内容。
答案 0 :(得分:1)
我将使用您的按钮创建一个UserControl。
我将在此答案中添加示例代码,但我不确定它是否对您完全有益。希望现在您有了一个灯泡时刻,看看这是如何实现的。我已经多次采用这种模式来解决您要描述的问题,并且非常合适。
您甚至可以将ContentPresenter控件放入按钮的内容中,并将该控件的Content
属性公开为另一个依赖属性,以提高绑定乐趣。绑定任何您喜欢的内容:更多文本,矩形等...或什么都不做。
随时发表评论,我很乐意对此进行充实...
答案 1 :(得分:0)
我通过使用DataTemplate
,带有附加属性将图像名称设置为字符串,使用IValueConverter
从字符串名称映射到Drawing
对象资源来解决问题绑定到OpacityMask
。
感谢这些资源:
<!-- Note the ordering of elements is important -->
<me:StringToStaticResourceConverter x:Key="ssr" />
<DataTemplate x:Key="inputSplitIconButtonContentTemplate">
<Rectangle Fill="{Binding Foreground, RelativeSource={RelativeSource AncestorType=Button}}" Width="12" Height="12">
<Rectangle.OpacityMask>
<DrawingBrush Drawing="{Binding Path=(me:Buttons.Image), Mode=OneWay, Converter={StaticResource ssr}, RelativeSource={RelativeSource AncestorType=Button}}" Stretch="Uniform" />
</Rectangle.OpacityMask>
</Rectangle>
</DataTemplate>
<Style x:Key="inputSplitIconButton" TargetType="Button" BasedOn="{StaticResource MetroCircleButtonStyle}">
<Setter Property="Margin" Value="0,-4,-4,2" />
<Setter Property="DockPanel.Dock" Value="Right" />
<Setter Property="Width" Value="32" />
<Setter Property="Height" Value="32" />
<Setter Property="TabIndex" Value="10" />
<Setter Property="ContentTemplate" Value="{StaticResource inputSplitIconButtonContentTemplate}" />
</Style>
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace MyProject
{
public static class Buttons
{
public static readonly DependencyProperty ImageProperty = DependencyProperty.RegisterAttached
(
name : "Image",
propertyType : typeof(String),
ownerType : typeof(Buttons),
defaultMetadata: new FrameworkPropertyMetadata( defaultValue: null, flags: FrameworkPropertyMetadataOptions.AffectsRender )
);
public static void SetImage(UIElement element, String value)
{
element.SetValue( ImageProperty, value );
}
public static String GetImage(UIElement element)
{
return (String)element.GetValue( ImageProperty );
}
}
public class StringToStaticResourceConverter : IValueConverter
{
public Object Convert(Object value, Type targetType, Object parameter, CultureInfo culture)
{
return Application.Current.FindResource( value );
}
public Object ConvertBack(Object value, Type targetType, Object parameter, CultureInfo culture)
{
return null;
}
}
}
<Button
Style="{StaticResource inputSplitIconButton}"
ToolTip="{x:Static me:Resources.Settings_BrowseFile}"
me:Buttons.Image="appbar_folder_ellipsis_drawing"
/>
它甚至也可以在WPF XAML设计器中使用!
我认为可以通过在{StaticResource appbar_folder_ellipsis_drawing}
中使用Window.xaml
并通过...时间来进行实验来简化!
当我意识到StringToStaticResourceConverter
也可以与附加属性一起使用时,我可以进一步简化解决方案并消除{StaticResource key}
。
Resources.xaml
中:
<me:StringToStaticResourceConverter x:Key="ssr" />
<DrawingBrush
行变为:<DrawingBrush Drawing="{Binding Path=(me:Buttons.Image), Mode=OneWay, RelativeSource={RelativeSource AncestorType=Button}}" Stretch="Uniform" />
Window.xaml
中:
{StaticResource}
,如下所示:me:Buttons.Image="{StaticResource appbar_folder_ellipsis_drawing}"
。