Активировать триггер от внешнего контроля

Новичок в WPF, извините за простой вопрос. Как заставить триггер запускаться в UserControl из элемента управления за пределами этого UserControl? Вот что я хочу сделать...

У меня есть UserControl с триггером, установленным для отображения изменения цвета фона на себе, когда IsMouseOver имеет значение True. Если я наведу указатель мыши на UserControl, триггер сработает, как я и ожидал. Что я хотел бы сделать, так это создать окно, содержащее UserControl и кнопку, и когда пользователь наводит указатель мыши на кнопку, запускает триггер UserControl. Что-то типа:

<Window x:Class="WpfApplication1.SimpleUCTry1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1.SimpleUCTry1"
Title="Window1" Height="300" Width="300">
<StackPanel>
    <local:Simple />
    <Button Content="Foo" />
</StackPanel>

So if the user mouses over the "Foo" button, the "Simple" UserControl's trigger would fire.

Это возможно?

Спасибо, Энди.


person Community    schedule 28.06.2009    source источник


Ответы (3)


Поскольку ваш элемент управления является «внешним» по отношению к кнопке, вы не можете использовать триггеры свойств или триггеры данных для отражения фона. Вам нужен EventTrigger на уровне окна.

Запустите анимацию ключевого кадра или дискретного цвета с длительностью 0 на MouseEnter и удалите указанную раскадровку на MouseLeave:

<Window.Triggers>
    <EventTrigger RoutedEvent="Mouse.MouseEnter" SourceName="button">
        <BeginStoryboard x:Name="Change_Control_Background_Start" 
            Storyboard="{StaticResource Change_Control_Background}"/>
    </EventTrigger>
    <EventTrigger RoutedEvent="Mouse.MouseLeave" SourceName="button">
        <RemoveStoryboard 
            BeginStoryboardName="Change_Control_Background_Start"/>
    </EventTrigger>
</Window.Triggers>
person Sergey Aldoukhov    schedule 28.06.2009
comment
Благодарю за ваш ответ! Можно ли также выполнить это с помощью EventSetter или RoutedUICommand? - person ; 29.06.2009
comment
Это можно сделать с помощью EventSetter, но для этого потребуется обработчик кода программной части (в этом случае вы даже можете обрабатывать события мыши непосредственно с помощью кнопки). Что касается RoutedUICommand, то это не очень хорошее совпадение. Команда — это то, что пользователь делает преднамеренно, и зависание не попадает в эту категорию. - person Sergey Aldoukhov; 29.06.2009

Ответ Сергея - это способ сделать это, если вам нужно что-то, что нельзя сделать с помощью EventTrigger, вы всегда можете обернуть свои элементы управления в DataTemplate и использовать ContentPresenter, чтобы показать это:

<Window x:Class="WpfApplication1.SimpleUCTry1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1.SimpleUCTry1"
    Title="Window1" Height="300" Width="300">
    <ContentPresenter Content="{Binding}">
        <ContentPresenter.ContentTemplate>
            <DataTemplate>
                <StackPanel>
                    <local:Simple Name="Ctrl1" />
                    <Button Name="Ctrl2" Content="Foo" />
                </StackPanel>
                <DataTemplate.Triggers>
                    <Trigger SourceName="Ctrl2" Property="IsMouseOver" Value="True">
                        <Setter TargetName="Ctrl1" Property="Background" Value="Blue"/>
                    </Trigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </ContentPresenter.ContentTemplate>
    </ContentPresenter>
</Window>
person Nir    schedule 29.06.2009
comment
Это хороший способ сделать это, так как у Энди уже есть UserControl. Просто добавьте к нему упомянутую кнопку (по определению она уже привязана к нему визуально) и используйте упомянутый трюк ContentPresenter. - person Sergey Aldoukhov; 29.06.2009

Еще один способ сделать это (требует некоторого кода, но, вероятно, самый чистый}

<StackPanel>
    <local:Simple Background="{Binding ElementName=bnFoo, 
                  Path=IsMouseOver, 
                  Converter={StaticResource boolToBackgroundConv}}"/>
    <Button Name="bnFoo" Content="Foo" />
</StackPanel>
person Sergey Aldoukhov    schedule 29.06.2009