Распространение события из стиля в MainWindow в WPF

У меня есть собственный стиль в отдельном XAML CustomTabItem.xaml который вызывает событие как:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                x:Class="myProject.CustomTabItem">
    ...
    ...

    <MenuItem Header="One">
        <MenuItem.Style>
            <Style TargetType="{x:Type MenuItem}">
                <EventSetter Event="Click" Handler="ClickNewSpaceOne"/>
            </Style>
        </MenuItem.Style>
    </MenuItem>

    ...
    ...

</ResourceDictionary>

И это легко вызывает событие в файле, который я создал CustomTabItem.xaml.cs:

namespace myProject
{
    partial class CustomTabItem
    {
        private void ClickNewSpaceOne(object sender, RoutedEventArgs e)
        {
            //do stuff here
        }
    }
}

Это все работает нормально, но теперь мне нужно поднять событие в MainWindow (конечно в обработчике событий ClickNewSpaceOne) но я не могу понять, как распространить это событие на MainWindow,

Я нашел эту статью, но на самом деле она не похожа на ту же самую ситуацию, поэтому я не очень ценю любую другую статью, которую я не нашел, или любой ответ.

1 ответ

Решение

Практика использования EventSetter в этом случае не самый лучший. И вот почему:

  • Он привязан к файлу BAML, что и должно быть обработчиком события

Поскольку он ограничен глобальной функцией события, он просто ищет обработчик события в xaml.cs файл. Кроме того, из-за этого MSDN:

Установщики событий нельзя использовать в стиле, который содержится в словаре ресурсов темы.

  • EventSetter не может быть установлен в триггере

Цитата из link:

Поскольку использование EventSetter для подключения обработчика событий является функцией времени компиляции, которая устанавливается через интерфейс IStyleConnector, существует другой интерфейс, называемый IComponentConnector, который используется компилятором XAML для подключения обработчика событий для автономных элементов XAML.

What alternatives?

1 - Attached dependency property

Используйте прикрепленное свойство зависимости и его UIPropertyMetadata Вы реализуете необходимую логику. Например:

// GetValue
// SetValue

public static readonly DependencyProperty SampleProperty =
                                      DependencyProperty.RegisterAttached("Sample",
                                      typeof(bool),
                                      typeof(SampleClass),
                                      new UIPropertyMetadata(false, OnSample));

private static void OnSample(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
    if (e.NewValue is bool && ((bool)e.NewValue) == true)
    {
        // do something...
    }
}

Более подробную информацию можно найти здесь:

Как унаследовать поведение кнопки в стиле WPF?

Выйти из приложения из пользовательского элемента управления

Как очистить содержимое PasswordBox при сбое входа в систему без привязки данных?

2 - Commands

Команда в WPF очень мощная. Цитата из MSDN:

Первая цель состоит в том, чтобы отделить семантику и объект, который вызывает команду, от логики, которая выполняет команду. Это позволяет нескольким разнородным источникам вызывать одну и ту же логику команд и позволяет настраивать логику команд для разных целей.

В этом случае они могут и должны использоваться в Styles, Templates, DataTemplates, В стиле вы можете установить команду следующим образом:

<Setter Property="Command" 
        Value="{Binding DataContext.YourCommand,
                RelativeSource={Relative Source AncestorType={x:Type Control}}}">

Кроме того, если вы хотите сослаться на команду, вы можете объявить команду как статическое свойство, тогда вы можете использовать Static расширение для ссылки на него.

3 - Using EventTrigger with Interactivity

В этом случае команда вызывается EventTrigger, Например:

<i:Interaction.Triggers>
    <i:EventTrigger EventName="MouseEnter" >
        <i:InvokeCommandAction Command="{Binding MyCommand}" />
    </i:EventTrigger>
</i:Interaction.Triggers>

Больше информации, можно найти здесь:

Использование EventTrigger в XAML для MVVM

Привязка событий WPF к командам MVVM Viewmodel

Другие вопросы по тегам