C# WPF Caliburn Micro TreeViewItem. Расширенное событие не запускается - PullRequest
2 голосов
/ 03 марта 2020

Я использую Caliburn Micro Message.Attach через XAML, чтобы попытаться связать события с моделью представления, но я не могу запустить событие TreeViewItem.Expanded. Другие события, такие как SetSelectedItem, работают нормально.

Я нашел другой вопрос по этому вопросу на SO здесь , но это не помогло в моем случае, поскольку не было предоставлено никакого контекста для ответа.

Единственная другая информация, которую я могу найти, - это следующий GitHub выпуск .

Внутренне Caliburn.Micro превращает <Button cm:Message.Attach="[Event Click] = [Action Test]" />

в

<Button>
   <i:Interaction.Triggers>
       <i:EventTrigger EventName="Click">
           <cm:ActionMessage MethodName="Test" />
       </i:EventTrigger>
   </i:Interaction.Triggers>
</Button>

Как вы заметили, EventTrigger не поддерживает вложенные события. При быстром осмотре всплыло Как подключить MVTM EventToCommand к событию Attached , которое показывает, как создать RoutedEventTrigger, который можно подключить к полному синтаксису.

Опять я попробовал этот подход, но не до конца понимаю, как это реализовать. Он запускает событие в пользовательском классе, но никогда не передается моему обработчику в модели представления.

Вот мой XAML (без предложения GitHub):

    <TreeView x:Name="FolderView"
                              cal:Message.Attach="[Event TreeViewItem.Expanded] = [Action Expanded($this)]; 
                              [Event SelectedItemChanged] = [Action SetSelectedItem($this.SelectedItem)]">
                        <TreeView.Resources>
                            <HierarchicalDataTemplate DataType="{x:Type models:LogicalDriveItem}" 
                                                      ItemsSource="{Binding Directories}"  >
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock VerticalAlignment="Center" Text="{Binding Path=DriveLetter}"></TextBlock>
                                </StackPanel>
                            </HierarchicalDataTemplate>
                            <HierarchicalDataTemplate DataType="{x:Type models:DirectoryItem}"
                                                      ItemsSource="{Binding Directories}">
                                <TextBlock VerticalAlignment="Center" Text="{Binding Path=Path}"></TextBlock>
                            </HierarchicalDataTemplate>
                        </TreeView.Resources>
                    </TreeView>

И мой посмотреть код модели:

    public void Expanded(object sender, RoutedEventArgs e)
    {
        // This won't fire
    }

    public void Expanded(object sender)
    {
        // Or this
    }

    public void SetSelectedItem(object sender)
    {
        // But this will
    }

1 Ответ

1 голос
/ 03 марта 2020

Ссылка, предоставленная mm8, решила мою проблему.

ОП в этом вопросе использует тот же вспомогательный класс RoutedEventTrigger, который я обнаружил на GitHub, но дополнительный контекст, предоставленный их ответом, был полезен. Используя вспомогательный класс RoutedEventTrigger, я обновил свой XAML следующим образом:

<i:Interaction.Triggers>
                    <!--in the routed event property you need to put the full name space and event name-->
                    <helpers:RoutedEventTrigger RoutedEvent="TreeViewItem.Expanded">
                        <cal:ActionMessage MethodName="Expanded">
                            <cal:Parameter Value="$eventArgs" />
                        </cal:ActionMessage>
                    </helpers:RoutedEventTrigger>
                </i:Interaction.Triggers>

, который теперь успешно запускает мое событие в коде ViewModel.

Обратите внимание, что $ это не сработало для меня, потому что элемент данных в моем случае является строкой. В моем случае это древовидное представление в стиле проводника. Для контекста, вот полный XAML:

<TreeView x:Name="FolderView">
                <i:Interaction.Triggers>
                    <!--in the routed event property you need to put the full name space and event name-->
                    <helpers:RoutedEventTrigger RoutedEvent="TreeViewItem.Expanded">
                        <cal:ActionMessage MethodName="Expanded">
                            <cal:Parameter Value="$eventArgs" />
                        </cal:ActionMessage>
                    </helpers:RoutedEventTrigger>
                </i:Interaction.Triggers>
                <TreeView.Resources>
                    <HierarchicalDataTemplate DataType="{x:Type models:LogicalDriveItem}" 
                                              ItemsSource="{Binding Directories}"  >
                        <StackPanel Orientation="Horizontal">
                            <!--<Image MaxWidth="20" Source="Images/Image.png"/>-->
                            <TextBlock VerticalAlignment="Center" Text="{Binding Path=DriveLetter}"></TextBlock>
                        </StackPanel>
                    </HierarchicalDataTemplate>
                    <HierarchicalDataTemplate DataType="{x:Type models:DirectoryItem}"
                                              ItemsSource="{Binding Directories}">
                        <TextBlock VerticalAlignment="Center" Text="{Binding Path=Name}"></TextBlock>
                    </HierarchicalDataTemplate>
                </TreeView.Resources>
            </TreeView>
...