在MVVM / WPF方案中,嵌套的UserControl事件不适用于EventTrigger / InvokeCommandAction

时间:2018-11-22 14:09:49

标签: c# wpf events mvvm prism

我正在使用带有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));
    }
}}

我苦苦挣扎的问题是,我无法捕获正在使用{的另一个ValueChanged的ViewModel上的两个已触发事件(SettingConfirmedUserControl) {1}}:

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> 捕获SettingConfirmed,但是由于我遵循的是MVVM模式,因此对我而言不起作用,这就是为什么我使用{ {1}}和RotationValueChangedEvent来捕捉EventTrigger上的那些事件,但是这些事件永远不会被解雇。 这是InvokeCommandAction

TransformViewModel

TransformViewModel从未被解雇,我根本不明白为什么。

我不知道这是否相关,但是Transform是另一个ViewModel上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() { } }} 的元素,该视图模型由PositionChangedObservableCollection<IComponent>呈现,内部带有ContentTemplateSelector的ListView

有人可以指出为什么发生这种情况以及如何解决它吗?

谢谢。

1 个答案:

答案 0 :(得分:2)

只要EventTrigger的{​​{1}}实际上是InvokeCommandAction,那么您的DataContextVector3View应该可以正常工作,因此绑定到{{1 }}属性成功。