简体   繁体   中英

C# WPF Caliburn Micro TreeViewItem.Expanded Event Not Firing

I'm using Caliburn Micro Message.Attach through XAML to try and bind Events to a View Model, but I cannot get the TreeViewItem.Expanded Event to fire. Other events like SetSelectedItem work fine.

I found another question on this on SO here but it was not helpful in my case as no context for the response was provided.

The only other information I can find is the following GitHub issue .

Internally Caliburn.Micro turns <Button cm:Message.Attach="[Event Click] = [Action Test]" />

into

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

As you noted, EventTrigger doesn't support attached events. A quick look around brought up How to attached an MVVM EventToCommand to an Attached event which shows how to create a RoutedEventTrigger that you could plug into the full syntax.

Again, I tried this approach, but don't fully understand how to implement this. It fires the event in the custom class, but never gets passed on to my handler in the View Model.

Here is my XAML (without the GitHub suggestion):

    <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>

And my view model code:

    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
    }

The link provided by mm8 resolved my issue.

The OP in that question is using the same RoutedEventTrigger helper class that I found on GitHub, but the additional context provided by their answer was helpful. Using the RoutedEventTrigger helper class, I updated my XAML to the following:

<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>

which now successfully fires my event in the ViewModel code.

Note that $this did not work for me because the data item in my case is a string. In my case, it's a File Explorer style Tree View. For context, here is the full 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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM