嵌套的 UserControl 事件在 MVVM/WPF 场景中不适用于 EventTrigger/InvokeCommandAction

Nested UserControl event doesn't work with EventTrigger/InvokeCommandAction in MVVM/WPF scenario

我正在使用带有 Prism (MVVM) 的 WPF,并尝试为几个 类 构建一个 Inspector。其中之一 类 是 Vector3:

<Grid x:Name="Vector3Root" Background="White">
    <StackPanel Orientation="Horizontal">
        <StackPanel Orientation="Horizontal">
            <xctk:DoubleUpDown Tag="X" Style="{StaticResource DoubleUpDownStyle}" Value="{Binding X}" ValueChanged="Vector3ValueChanged"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <xctk:DoubleUpDown Tag="Y" Style="{StaticResource DoubleUpDownStyle}" Value="{Binding Y}" ValueChanged="Vector3ValueChanged"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <xctk:DoubleUpDown Tag="Z" Style="{StaticResource DoubleUpDownStyle}" Value="{Binding Z}" ValueChanged="Vector3ValueChanged"/>
        </StackPanel>
    </StackPanel>
</Grid>

及其代码隐藏

namespace SimROV.WPF.Views{
public partial class Vector3View : UserControl
{
    public Vector3View()
    {
        InitializeComponent();
    }

    public static readonly RoutedEvent SettingConfirmedEvent =
        EventManager.RegisterRoutedEvent("SettingConfirmed", RoutingStrategy.Bubble,
        typeof(RoutedEventHandler), typeof(Vector3View));

    public event RoutedEventHandler SettingConfirmed
    {
        add { AddHandler(SettingConfirmedEvent, value); }
        remove { RemoveHandler(SettingConfirmedEvent, value); }
    }

    public void Vector3ValueChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        RaiseEvent(new RoutedEventArgs(SettingConfirmedEvent));
    }
}}

我正在努力解决的问题是我无法在另一个 UserControl 的 ViewModel 上捕捉到触发的事件(ValueChangedSettingConfirmed)使用 Vector3View:

<UserControl
         x:Class="SimROV.WPF.Views.TransformView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:views="clr-namespace:SimROV.WPF.Views"
         xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
         xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
         xmlns:prism="http://prismlibrary.com/"

mc:Ignorable="d" >

<Grid x:Name="TransformRoot" Background="White">
    <StackPanel Orientation="Vertical">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Position" Margin="5"/>
            <!--<ContentPresenter ContentTemplate="{StaticResource Vector3Template}"/>-->
            <views:Vector3View x:Name="PositionVector3">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="SettingConfirmed">
                        <prism:InvokeCommandAction Command="{Binding PositionValueChangedCommand}"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </views:Vector3View>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Rotation" Margin="5"/>
            <!--<ContentPresenter ContentTemplate="{StaticResource Vector3Template}"/>-->
            <views:Vector3View x:Name="RotationVector3" SettingConfirmed="RotationValueChangedEvent"/>
        </StackPanel>
    </StackPanel>
</Grid>

此时我可以在代码隐藏中使用 RotationValueChangedEvent 捕获 SettingConfirmed,但由于我遵循 MVVM 模式,这对我不起作用,这就是我的原因使用 EventTriggerInvokeCommandAction 来捕获 TransformViewModel 上的那些事件,但这些事件永远不会被触发。 这是 TransformViewModel:

namespace SimROV.WPF.ViewModels{
public class TransformViewModel : BindableBase
{
    private ICommand _positionCommand;

    public ICommand PositionValueChangedCommand => this._positionCommand ?? (this._positionCommand = new DelegateCommand(PositionChanged));
    private void PositionChanged()
    {

    }
    public TransformViewModel()
    {

    }
}}

PositionChanged 从来没有被解雇过,我完全不明白为什么。

我不知道这是否相关,但 Transform 是另一个 ViewModel 中 ObservableCollection<IComponent> 的一个元素,它由 ListViewItemContainerStyle 呈现,里面有一个 ContentPresenter 和一个 ContentTemplateSelector。

谁能告诉我为什么会发生这种情况以及如何解决它?

谢谢。

你的 EventTriggerInvokeCommandAction 应该可以正常工作,前提是 Vector3ViewDataContext 实际上是 TransformViewModel 所以绑定到 PositionValueChangedCommand 属性 成功。