Как передать свойство Datatemplate's Datatype в Caliburn.Micros Message.Attach? - PullRequest
1 голос
/ 12 октября 2019

В настоящее время я занимаюсь внедрением системы навигации по меню для группового проекта. Мы используем Caliburn.Micro и шаблон MVVM.

Меню находится в ShellView.xaml и основано на List<NavigationMenuItem>, который был отфильтрован с использованием свойства Role.

public class NavigationMenuItem
    {
        public IScreen ViewModel { get; set; }
        public string IconPath { get; set; }

        public string Role { get; set; }

        public NavigationMenuItem(IScreen viewModel, string iconPath, string role)
        {
            ViewModel = viewModel;
            IconPath = iconPath;
            Role = role;
        }
    }

Меню отображается очень хорошо, но теперь я хочу передать свойство ViewModel методу в ShellViewModel.cs, чтобы я мог активировать изменение вида. Вот как выглядит ShellView.xaml:

<Window
    x:Class="P3GG.Views.ShellView"
    xmlns:cal="http://www.caliburnproject.org"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:P3GG.Views"
    xmlns:models="clr-namespace:P3GG.Models"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:templates="clr-namespace:P3GG.Templates"
     xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
    Title="Title"
    Width="800"
    Height="600"
    WindowStartupLocation="CenterScreen"
    mc:Ignorable="d">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <ListBox Visibility="{Binding SidebarIsVisible, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Collapsed}"
                 Grid.Column="0"
                 Background="#333333"
                 x:Name="NavigationMenu">
            <ListBox.ItemTemplate>
                <DataTemplate DataType="models:NavigationMenuItem">
                    <Button cal:Message.Attach="Handle( <!-- pass content of NavigationMenuItem.ViewModel --> )" Style="{StaticResource BtnSidebar}">
                        <Image Margin="20" Source="{Binding IconPath}"/>
                    </Button>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <ContentControl  Grid.Column="1" x:Name="ActiveItem"/>
    </Grid>
</Window>

ShellViewModel.cs в настоящее время содержит два метода Handle:

public void Handle(Screen screen)
public void Handle(User user)

Как передать свойство ViewModel данного NavigationMenu к методу Handle(Screen)?

РЕДАКТИРОВАТЬ Добавлен метод Handle для запроса

public void Handle(Screen screen)
        {
            if (screen is LoginViewModel)
            {
                SidebarIsVisible = false;
                NotifyOfPropertyChange(() => SidebarIsVisible);
            }
            else
            {
                SidebarIsVisible = true;
                NotifyOfPropertyChange(() => SidebarIsVisible);
            }
            ActivateItem(screen);
        }

1 Ответ

0 голосов
/ 12 октября 2019

Может быть, вы можете попробовать что-то вроде этого, как объяснено здесь :

<Button cal:Message.Attach="[Event Click] = [Action Handle($dataContext)]" Style="{StaticResource BtnSidebar}">
    <Image Margin="20" Source="{Binding IconPath}"/>
</Button>

Это передаст модель полного вида (DataContext) вашему обработчику.

Чтобы передать определенное свойство вашей модели представления , используйте длинный синтаксис, указанный здесь :

<Button Style="{StaticResource BtnSidebar}">
    <i:Interaction.Triggers> 
        <i:EventTrigger EventName="Click"> 
            <cal:ActionMessage MethodName="Handle"> 
               <cal:Parameter Value="{Binding ViewModel}" /> 
            </cal:ActionMessage> 
        </i:EventTrigger> 
    </i:Interaction.Triggers> 
    <Image Margin="20" Source="{Binding IconPath}"/>
</Button>

с i, определенным как

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

Вы также можете изменить DataContext свойство Button на интересующее свойство, например:

<Button DataContext="{Binding ViewModel}" cal:Message.Attach="[Event Click] = [Action Handle($dataContext)]" Style="{StaticResource BtnSidebar}">
    <Image Margin="20" Source="{Binding IconPath}"/>
</Button>

, чтобы только правильное свойство передавалось вашему хендлеру, но эточувствует себя как взломатьПри щелчке это передаст DataContext Button как параметр вашего Handle метода, который должен быть NavigationMenuItem.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...