Триггер огня в UserControl на основе DependencyProperty

У меня очень простой вопрос, но, кажется, я не смог найти на него ответ в Интернете. Возможно, потому что я не там ищу.

У меня есть пользовательский элемент управления с DependencyProperty пользовательского типа перечисления. В XAML я хотел бы показать/скрыть элементы на основе значения типа перечисления. Я пытался сделать это с помощью DataTriggers, но у меня не получилось.

<UserControl x:Class="WpfApplication1.DisplayIcon"
         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" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="50" d:DesignWidth="50"
         x:Name="control">
<UserControl.Resources>
    <Style TargetType="Ellipse">
        <Setter Property="Visibility" Value="Collapsed"/>
        <Style.Triggers>
            <DataTrigger Value="Ellipse" Binding="{Binding MyIconType, ElementName=control}">
                <Setter Property="Visibility" Value="Visible"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>

    <Style TargetType="Rectangle">
        <Setter Property="Visibility" Value="Collapsed"/>
        <Style.Triggers>
            <DataTrigger Value="Rectangle" Binding="{Binding MyIconType, ElementName=control}">
                <Setter Property="Visibility" Value="Visible"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>

</UserControl.Resources>
<Grid>
    <Ellipse x:Name="el1" Fill="Red" Width="30" Height="30" />
    <Rectangle x:Name="el2" Fill="Green" Width="20" Height="20" /> 
    <TextBlock Text="{Binding MyIconType, ElementName=control}" Margin="0,40,0,0"/>
</Grid></UserControl>

И мой код выглядит так:

public enum IconType
{
    Ellipse,
    Rectangle
}
public partial class DisplayIcon : UserControl
{
    public DisplayIcon()
    {
        InitializeComponent();
    }

    public IconType MyIconType
    {
        get { return (IconType)GetValue(MyIconTypeProperty); }
        set { SetValue(MyIconTypeProperty, value); }
    }

    // Using a DependencyProperty as the backing store for MyIconType.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty MyIconTypeProperty =
        DependencyProperty.Register("MyIconType", typeof(IconType), typeof(DisplayIcon), new PropertyMetadata(IconType.Ellipse));

}

Кто-нибудь может мне помочь?

Спасибо,

Джим


person jim    schedule 05.07.2013    source источник


Ответы (1)


Вы можете создать Style для каждого элемента и определить там триггеры:

<UserControl x:Class="WpfApplication1.DisplayIcon"
     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" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     mc:Ignorable="d" 
     d:DesignHeight="50" d:DesignWidth="50"
     x:Name="control">

<UserControl.Resources>

    <Style TargetType="Ellipse">
        <Style.Triggers>
            <DataTrigger Value="Rectangle" Binding="{Binding MyIconType, ElementName=control}">
                <Setter Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>

    <Style TargetType="Rectangle">
        <Style.Triggers>
            <DataTrigger Value="Ellipse" Binding="{Binding MyIconType, ElementName=control}">
                <Setter Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>

</UserControl.Resources>

<Grid>
    <Ellipse x:Name="el1" Fill="Red" Width="20" Height="20"/>
    <Rectangle Grid.Row="1" x:Name="el2" Fill="Green" Width="20" Height="20"/>
</Grid>

EDIT:

На самом деле, вероятно, было бы разумнее инвертировать логику Visibility. Таким образом, вы можете добавлять фигуры без изменения кода:

<UserControl x:Class="WpfApplication1.DisplayIcon"
     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" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     mc:Ignorable="d" 
     d:DesignHeight="50" d:DesignWidth="50"
     x:Name="control">

<UserControl.Resources>

    <Style TargetType="Ellipse">
        <Setter Property="Visibility" Value="Collapsed"/>
        <Style.Triggers>
            <DataTrigger Value="Ellipse" Binding="{Binding MyIconType, ElementName=control}">
                <Setter Property="Visibility" Value="Visible"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>

    <Style TargetType="Rectangle">
        <Setter Property="Visibility" Value="Collapsed"/>
        <Style.Triggers>
            <DataTrigger Value="Rectangle" Binding="{Binding MyIconType, ElementName=control}">
                <Setter Property="Visibility" Value="Visible"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>

</UserControl.Resources>

<Grid>
    <Ellipse x:Name="el1" Fill="Red" Width="20" Height="20"/>
    <Rectangle x:Name="el2" Fill="Green" Width="20" Height="20"/>
</Grid>

person Richard E    schedule 05.07.2013
comment
Спасибо за ответ, но это тоже не работает. Триггеры не срабатывают. - person jim; 05.07.2013
comment
Я скопировал ваш код, и он не работает. У вас есть рабочая копия? - person jim; 05.07.2013
comment
Я проверил это, изменив значение MyIconType в обработчике нажатия кнопки. У меня работает: private void ButtonBase_OnClick (отправитель объекта, RoutedEventArgs e) { if (MyIconType == IconType.Ellipse) MyIconType = IconType.Rectangle; else { MyIconType = IconType.Ellipse; } } - person Richard E; 05.07.2013
comment
Я использую его в MainWindow со следующим XAML (и он не работает). Любые подсказки? ‹Window x:Class=WpfApplication1.MainWindow xmlns=schemas.microsoft.com/winfx/2006 /xaml/presentation xmlns:x=schemas.microsoft.com/winfx/2006/ xaml Title=MainWindow Height=350 Width=525 xmlns:local=clr-namespace:WpfApplication1› ‹Grid› ‹local: DisplayIcon MyIconType=Ellipse/› ‹/Grid› ‹/Window› - person jim; 05.07.2013
comment
Точно сказать не могу. Я скопировал ваш код MainWindow, и он просто отобразил эллипс. Изменил MyIconType на Rectangle, и он просто отобразил прямоугольник. - person Richard E; 05.07.2013
comment
Я снова обновил код, и теперь он работает. Странное поведение. - person jim; 05.07.2013