事件到 VisualStateGroup 的 ViewModel 方法

Event to ViewModel Method for VisualStateGroup

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

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

但是,VisualStateGroupCurrentStateChanged 事件没有成功,如下所示(是的,嵌套在 <VisualStateGroup> 块,因为 CurrentStateChanged 事件属于 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 事件(或使用其他方法),我非常想知道。

However, no success when it comes to the CurrentStateChanged event of VisualStateGroup as shown below

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

可行的方法是创建一个专门针对这种情况的自定义行为,请参阅Marco Minerva[=25=写的this blog ]

这个行为可以帮助我们监控当前的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 名称。