wpf TreeView -尽管命中断点,RelayCommand仍不执行

jv2fixgn  于 2023-03-04  发布在  其他
关注(0)|答案(1)|浏览(167)

我有一个具有ItemTemplate/HierarchicalDataTemplate的TreeView。当我展开TreeViewItem时,我希望触发MessageBox。我目前遇到的问题是,尽管在ViewModel中的RelayCommand()上命中断点,但实际的MessageBox不会执行。
我尝试在KeyViewModel本身内部移动命令,也发生了相同的行为。

可重现项目:https://github.com/MemeMachineSO/TreeViewProblem

XAML:

<Window x:Class="TreeViewProblem.MainWindow"
        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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TreeViewProblem"
        xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <TreeView Grid.Row="1" Grid.Column="0" Name="RegistryTreeView" ItemsSource="{Binding Keys}">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding SubKeys}">
                    <TreeViewItem Header="{Binding name}">
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="Expanded">
                                <i:InvokeCommandAction Command="{Binding ElementName=RegistryTreeView, Path=DataContext.TreeViewItemExpanded}"/>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </TreeViewItem>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    </Grid>
</Window>
dgiusagp

dgiusagp1#

首先,在属性的getter中设置断点,MessageBox.Show方法在命令 * executes * 时调用,在InvokeCommandAction绑定到属性本身时不调用。
其次,HierarchicalDataTemplate不应该包含TreeViewItem,控件创建自己的TreeViewItem容器,模板中的Expanded事件永远不会被触发。
除非您为TreeView定义了一个(完整的)自定义模板,否则使用EventTrigger在这里不起作用。
相反,您可以定义一个ItemContainerStyle并以编程方式调用该命令:

public partial class MainWindow : Window
{
    private readonly MainWindowViewModel _viewModel = new MainWindowViewModel();
    public MainWindow()
    {
        InitializeComponent();
        DataContext = _viewModel;
    }

    private void TreeViewItem_Expanded(object sender, RoutedEventArgs e) =>
        _viewModel.TreeViewItemExpanded.Execute(null);
}
    • XAML格式:**
<TreeView Grid.Row="1" Grid.Column="0" Name="RegistryTreeView" ItemsSource="{Binding Keys}">
    <TreeView.ItemContainerStyle>
        <Style TargetType="TreeViewItem">
            <EventSetter Event="Expanded" Handler="TreeViewItem_Expanded" />
        </Style>
    </TreeView.ItemContainerStyle>
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding SubKeys}">
            <TextBlock Text="{Binding name}" />
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

不,当您从同一个视图调用同一个命令时,这 * 不会 * 破坏MVVM模式。MVVM不是要消除代码,而是要分离关注点。无论您是从视图的代码隐藏调用视图模型命令,还是使用同一个视图的XAML标记中的EventTriggerInvokeCommandAction,都与模式无关。

相关问题