我正在尝试为背景和背景颜色创建一个带有png图像的<Button/>
。
可能还不知道 png图片来源,所以我不能放 他们在模板中。
我有Style
看起来像这样:
<Style x:Key="MyButton" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border CornerRadius="0">
<Image Margin="0" Source="/MyApp;component/Images/my-image.png" Stretch="None" />
<Border.Style>
<Style TargetType="{x:Type Border}">
<Setter Property="Background" Value="LimeGreen" />
</Style>
</Border.Style>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
它给了我一个按钮,在一个坚实的LimeGreen背景上有一个png图像。
我的MainWindow.xaml
看起来有点像这样:
<Button Style="{StaticResource MyButton}" Click="btnMine_Click" /* some other props */ />
它背后的代码是这样的:
private void btnMine_Click(object sender, RoutedEventArgs e)
{
// TODO: change the image src on this button
var myButton = sender as Button;
// This won't work:
// myButton.Border.Image.Source = getNewImageString();
}
如何将图像来源从/MyApp2;component/Images/my-image.png
更改为其他内容?
答案 0 :(得分:1)
叹息,在Windows窗体中它实际上是一行。在WPF中看起来它将是几百个。
那是因为这是你可以放在winforms按钮中的唯一的东西。 WPF是一个真正的UI框架,而不是一些随机半弃的恐龙,只允许做默认的东西(顺便说一句看起来很可怕)。
选项1:将图片放置为按钮Content
:
如果你只是想在按钮中放置一个图像而没有别的,为什么不这样做呢?
<Style TargetType="Button">
<Setter Property="Background" Value="LimeGreen"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}">
<ContentPresenter ContentSource="Content"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
然后:
<Button>
<!-- Background not set, defaults to what's set in the Style -->
<Image Source="./ChessPieces/BlackKnight.png"/>
</Button>
<Button Background="Red">
<Image Source="./ChessPieces/BlackBishop.png"/>
</Button>
<Button Background="Blue">
<Image Source="./ChessPieces/BlackPawn.png"/>
</Button>
<!-- WPF's idea of "Dynamic" is not the same as win(hack)forms' -->
<Button Background="White">
<Image Source="{Binding SomeStringPropertyDefinedInAViewModel}"/>
</Button>
结果:
选项2(不是很优雅):使用Tag
属性:
如果除了Image之外,你想在Button中添加其他东西,你可以采用一种有点hacky的方法将ImageSource放在Button的Tag
属性中。
<Style TargetType="Button">
<Setter Property="Background" Value="LimeGreen"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Tag, RelativeSource={RelativeSource TemplatedParent}}"
Height="50" Width="50"/>
<ContentPresenter ContentSource="Content"/>
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
然后:
<Button Tag="./ChessPieces/BlackKnight.png"
Background="Blue"
Foreground="White"
Content="Some Text"/>
<Button Tag="./ChessPieces/BlackBishop.png"
Background="LightGray">
<CheckBox Content="A CheckBox!" VerticalAlignment="Center"/>
</Button>
结果:
选项3:使用Attached Property
与选项2相同,但使用在其他地方声明的属性,例如:
<Button ButtonImage.Source="./ChessPieces/BlackBishop.png"
<!-- etc -->
选项4:创建自定义控件:
创建一个派生自Button的类(没有XAML的.cs文件)并添加DependencyProperty
来保存图像,然后将模板设置为该值并使用该值。
选项5:MVVM
创建ButtonViewModel
,或者实际使用ViewModel中声明的DelegateCommand来绑定Button的属性。
不是选项:遍历可视树并更改代码中的Image.Source
。
这不是你想要做的事情。这根本不是一个好方法。
我可以永远继续下去,但我必须去睡觉。如果您希望我详细说明这些方法,请告诉我。
答案 1 :(得分:0)
有几种想法:
我认为最好的解决方案是创建用户控件并将图像源作为依赖属性,请参阅:http://www.codeproject.com/Articles/224230/Exploring-the-use-of-Dependency-Properties-in-User
通过这种方式,您将拥有一个随时可用的“自定义”控件,它支持您所使用的内容并允许您直接引用它并使用绑定,这样您就可以避免使用样式的混乱解决方案。
经过讨论和扩展要求后,请参阅: