从父元素触发

时间:2013-02-17 20:30:04

标签: wpf triggers custom-controls

我在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值。它编译,但它不会触发任何东西。

此示例中的边距太大,但只是为了更好地了解问题。

1 个答案:

答案 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>

enter image description here