Меню и подменю Dynami c с Caliburn Micro, как я могу привязать команды? - PullRequest
0 голосов
/ 27 мая 2020

Я использую Caliburn Micro в проекте WPF, где я хочу, чтобы компоненты подключаемого модуля могли заполнять панель инструментов. Каждый плагин получает элемент меню верхнего уровня и может по своему выбору заполнять его подменю.

Example

<ToolBar>
    <Menu x:Name="ToolBarMenuItems">
        <Menu.ItemContainerStyle>
            <Style TargetType="{x:Type MenuItem}">
                <Setter Property="Header" Value="{Binding Path=Text}" />
                <Setter Property="ItemsSource" Value="{Binding Path=Children}" />
            </Style>
        </Menu.ItemContainerStyle>
    </Menu>
</ToolBar>

ToolBarMenuItems - это BindableCollection интерфейса:

public BindableCollection<IMenuItemViewModel> ToolBarMenuItems { get; set; }

public interface IMenuItemViewModel
{
    string Text { get; set; }

    ObservableCollection<IMenuItemViewModel> Children { get; set; }

    bool CanRunCommand();

    void RunCommand();
}

Это отлично работает в том, что касается создания меню, проблема заключается в подключении пунктов меню к RunCommand / CanRunCommand. Dynami c меню с Caliburn micro объяснил, как это сделать в MenuItem:

<Menu>
    <MenuItem x:Name="ToolBarMenuItems" DisplayMemberPath="Text" Header="MyMenu" cal:Message.Attach="RunToolbarCommand($originalsourcecontext)"/>
</Menu>

Где RunToolBarCommand - это метод в модели представления public void RunToolbarCommand(IMenuItemViewModel menuItem), а $ originalsourcecontext относится к настройке следующее в загрузчике

MessageBinder.SpecialValues.Add("$originalsourcecontext", context =>
{
    var args = context.EventArgs as RoutedEventArgs;
    var fe = args?.OriginalSource as FrameworkElement;
    return fe?.DataContext;
});

Но, как я уже сказал, мне нужно сделать это для всего меню, а не только для MenuItem, но я не знаю, как использовать Caliburn Micro для привязки методов .

1 Ответ

1 голос
/ 28 мая 2020

Добавьте сеттер в свой Style, который устанавливает присоединенное свойство cal:Message.Attach и передает $executionContext:

<Menu x:Name="ToolBarMenuItems">
    <Menu.ItemContainerStyle>
        <Style TargetType="{x:Type MenuItem}">
            <Setter Property="Header" Value="{Binding Path=Text}" />
            <Setter Property="ItemsSource" Value="{Binding Path=Children}" />
            <Setter Property="cal:Message.Attach" Value="RunCommand($executionContext)" />
        </Style>
    </Menu.ItemContainerStyle>
</Menu>

. Вам нужен контекст в вашем интерфейсе и реализации, чтобы иметь возможность останавливать событие от bubbeling:

public void RunCommand(ActionExecutionContext context)
{
    if (context?.EventArgs is RoutedEventArgs routedEventArgs)
        routedEventArgs.Handled = true;

    MessageBox.Show("Run!");
}

Пожалуйста, обратитесь к этому вопросу для получения дополнительной информации об этом.

...