2013-02-17 4 views
0

Я написал небольшой пользовательский элемент управления в WPF, чтобы использовать кнопку с текстом и изображением. Это называется IconButton. Теперь я добавил свойство «Ориентация», чтобы позволить оставить изображение или верхнюю часть текста. Но тогда край изображения должен быть другим. Но я не могу сказать изображению, чтобы установить его маржу в соответствии с ориентацией родительского StackPanel.Триггер из родительского элемента

Вот код 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, и эти триггеры сбивают меня с ума.

Моя попытка в коде XAML в строке 26, где я хочу запросить значение StackPanel.Orientation. Он компилируется, но ничего не вызывает.

Поля в этом примере слишком велики, но только для лучшей видимости проблемы.

ответ

1

Кажется, лет явным образом установить Margin на Image, вы должны двигаться, что в StyleSetter иначе Trigger обыкновение изменить значение, как это обыкновение переопределять явно заданное значение.

Также может быть проще использовать DataTrigger, чтобы установить Margin, так как у вас есть Orientation зависимая собственность в классе.

Что-то вроде этого должно работать для вашего ImageStyle.

<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

+0

Спасибо, что работает просто отлично. – ygoe

Смежные вопросы