嵌套的 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 上捕捉到触发的事件(ValueChanged
或 SettingConfirmed
)使用 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 模式,这对我不起作用,这就是我的原因使用 EventTrigger
和 InvokeCommandAction
来捕获 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>
的一个元素,它由 ListView
和 ItemContainerStyle
呈现,里面有一个 ContentPresenter
和一个 ContentTemplateSelector。
谁能告诉我为什么会发生这种情况以及如何解决它?
谢谢。
你的 EventTrigger
和 InvokeCommandAction
应该可以正常工作,前提是 Vector3View
的 DataContext
实际上是 TransformViewModel
所以绑定到 PositionValueChangedCommand
属性 成功。
我正在使用带有 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 上捕捉到触发的事件(ValueChanged
或 SettingConfirmed
)使用 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 模式,这对我不起作用,这就是我的原因使用 EventTrigger
和 InvokeCommandAction
来捕获 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>
的一个元素,它由 ListView
和 ItemContainerStyle
呈现,里面有一个 ContentPresenter
和一个 ContentTemplateSelector。
谁能告诉我为什么会发生这种情况以及如何解决它?
谢谢。
你的 EventTrigger
和 InvokeCommandAction
应该可以正常工作,前提是 Vector3View
的 DataContext
实际上是 TransformViewModel
所以绑定到 PositionValueChangedCommand
属性 成功。