我在WPF中编写了一个小用户控件,以便使用带有文本和图像的按钮。它被称为IconButton。现在我添加了一个属性“Orientation”以允许图像留在文本的顶部或顶部。但是,图像边距必须不同。但我无法告诉图像根据父StackPanel的Orientation设置其边距。
这是XAML代码:
<Button
x:Class="MyNamespace.IconButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="_this">
<Button.Template>
<ControlTemplate>
<Button
Padding="{TemplateBinding Padding}"
Style="{TemplateBinding Style}"
Command="{TemplateBinding Button.Command}">
<StackPanel Name="StackPanel" Orientation="{Binding Orientation, ElementName=_this}">
<Image Name="Icon"
Source="{Binding IconSource, ElementName=_this}"
VerticalAlignment="Center"
Margin="0,0,10,0">
<Image.Style>
<Style>
<Style.Triggers>
<Trigger Property="Button.IsEnabled" Value="False">
<Setter Property="Image.Opacity" Value="0.3"/>
</Trigger>
<Trigger Property="StackPanel.Orientation" Value="Vertical">
<Setter Property="Image.Margin" Value="0,0,0,10"/>
</Trigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<ContentPresenter
Visibility="{Binding ContentVisibility, ElementName=_this}"
RecognizesAccessKey="True"
Content="{Binding Content, ElementName=_this}"
VerticalAlignment="Center"/>
</StackPanel>
</Button>
</ControlTemplate>
</Button.Template>
</Button>
这是代码隐藏的C#代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace MyNamespace
{
public partial class IconButton : Button
{
public static DependencyProperty IconSourceProperty = DependencyProperty.Register(
"IconSource",
typeof(ImageSource),
typeof(IconButton));
public static DependencyProperty ContentVisibilityProperty = DependencyProperty.Register(
"ContentVisibility",
typeof(Visibility),
typeof(IconButton),
new PropertyMetadata(Visibility.Collapsed));
public static DependencyProperty OrientationProperty = DependencyProperty.Register(
"Orientation",
typeof(Orientation),
typeof(IconButton),
new PropertyMetadata(Orientation.Horizontal));
public ImageSource IconSource
{
get { return (ImageSource) GetValue(IconSourceProperty); }
set { SetValue(IconSourceProperty, value); }
}
public Visibility ContentVisibility
{
get { return (Visibility) GetValue(ContentVisibilityProperty); }
set { SetValue(ContentVisibilityProperty, value); }
}
public Orientation Orientation
{
get { return (Orientation) GetValue(OrientationProperty); }
set { SetValue(OrientationProperty, value); }
}
public IconButton()
{
InitializeComponent();
}
protected override void OnContentChanged(object oldContent, object newContent)
{
base.OnContentChanged(oldContent, newContent);
ContentVisibility = (newContent is string ? !string.IsNullOrEmpty((string) newContent) : newContent != null) ? Visibility.Visible : Visibility.Collapsed;
}
}
}
我不知道如何让它发挥作用。我仍然是WPF的新手,这些触发器让我发疯。
我的尝试是在第26行的XAML代码中,我想查询StackPanel.Orientation值。它编译,但它不会触发任何东西。
此示例中的边距太大,但只是为了更好地了解问题。
答案 0 :(得分:2)
似乎您已明确设置Margin
上的Image
,您应将其移至Style
Setter
,否则Trigger
不会更改值因为它不会覆盖明确设定的值。
使用DataTrigger
设置Margin
可能会更容易,因为您在类中拥有Orientation
依赖属性。
这样的内容适用于Image
Style
。
<Image Name="Icon" Source="{Binding IconSource, ElementName=_this}" VerticalAlignment="Center">
<Image.Style>
<Style TargetType="{x:Type Image}">
<!-- move set margin to here -->
<Setter Property="Margin" Value="0,0,10,0"/>
<Style.Triggers>
<Trigger Property="Button.IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.3"/>
</Trigger>
<!-- set a DataTrigger to bind to the value of Orientation-->
<DataTrigger Binding="{Binding Orientation, ElementName=_this}" Value="Vertical">
<Setter Property="Margin" Value="0,0,0,10"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>