VisualStateGroup的事件到ViewModel方法

本文关键字:ViewModel 方法 事件 VisualStateGroup | 更新日期: 2023-09-27 18:20:46

我已经使用EventTriggerBehaviorCallMethodAction成功地将事件转换为方法(用于ViewModel),如以下示例所示(此处选择了一个PageLoaded事件进行说明)。

<i:Interaction.Behaviors> <core:EventTriggerBehavior EventName="Loaded"> <core:CallMethodAction TargetObject="{Binding Mode=OneWay}" MethodName="PageLoadedCommand"/> </core:EventTriggerBehavior> </i:Interaction.Behaviors>

但是,当涉及到VisualStateGroupCurrentStateChanged事件时,没有成功,如下所示(是的,嵌套在<VisualStateGroup>块中,因为urrentStateChanged事件属于VisualStateGroup):

<i:Interaction.Behaviors> <core:EventTriggerBehavior EventName="CurrentStateChanged"> <core:CallMethodAction MethodName="CurrentVisualStateChanged" TargetObject="{Binding Mode=OneWay}"/> </core:EventTriggerBehavior> </i:Interaction.Behaviors>

我怀疑VisualStateGroup(或VisualStateManager)和CurrentStateChanged事件可能存在问题。我这么说是因为,我可以将这种方法用于其他活动。我已经检查并重新检查了CallMethodAction方法签名(传递格式的事件参数),但没有机会。

如果您像上面那样(或使用其他方法)成功地触发了CurrentStateChanged事件,我非常想知道。

VisualStateGroup的事件到ViewModel方法

然而,当涉及到VisualStateGroup的CurrentStateChanged事件时,没有成功,如下所示

是的,EventTriggerBehavior不适用于VisualStateGroup.CurrentStateChanged事件。

可行的方法是创建一个专门针对该场景的自定义行为,请参阅Marco Minerva撰写的博客

这种行为可以帮助我们监控当前的VisualStatus,在自定义属性(ViewModelState类型)的Set方法中,根据您的意愿调用方法:

public class MainViewModel : ViewModelBase
{
        public enum ViewModelState
        {
            Default,
            Details
        }
        private ViewModelState currentState;
        public ViewModelState CurrentState
        {
            get { return currentState; }
            set
            {
                this.Set(ref currentState, value);
                OnCurrentStateChanged(value);
            }
        }
        public RelayCommand GotoDetailsStateCommand { get; set; }
        public RelayCommand GotoDefaultStateCommand { get; set; }
        public MainViewModel()
        {
            GotoDetailsStateCommand = new RelayCommand(() =>
            {
                CurrentState = ViewModelState.Details;
            });
            GotoDefaultStateCommand = new RelayCommand(() =>
            {
                CurrentState = ViewModelState.Default;
            });
        }
        public void OnCurrentStateChanged(ViewModelState e)
        {
            Debug.WriteLine("CurrentStateChanged: " + e.ToString());
        }
}

请检查我在Github上完成的样本

可能是由于最新的SDK,我设法使它与动态绑定(用于事件到方法模式)一起工作,如下所示。

在XAML中将CurrentStateChanged事件绑定为:

<VisualStateGroup CurrentStateChanged="{x:Bind ViewModel.CurrentVisualStateChanged}">

在ViewModel中,为CurrentStateChanged()方法提供CurrentStateChanged事件签名,如下所示:

public void CurrentVisualStateChanged(object sender, VisualStateChangedEventArgs e)
{
    var stateName = e?.NewState.Name;  // get VisualState name from View
    ...
    // more code to make use of the VisualState
}

上面的内容不久前对我不起作用,现在我在VS2015更新2之后尝试了,我怀疑最新的SDK得到了增强??不管怎样,现在您可以通过动态绑定获得视图模型中的VisualState名称,这是一个好消息。