将 VisualStateManager VisualState 绑定到视图模型?
Bind VisualStateManager VisualState to view model?
我的网格具有三个不同的 VisualState。我如何将此信息绑定到我的视图模型,因为我需要根据视图状态做不同的事情。
现在我正在使用 CurrentStateChanged 事件(这不是很 mvvm 的方式)但主要问题是打开应用程序时不会触发该事件,所以我不知道初始视觉状态。
我目前的看法:
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="AdaptiveVisualStateGroup" CurrentStateChanged="{x:Bind ViewModel.ViewStateChanged, Mode=OneWay}">
<VisualState x:Name="VisualStateNarrow">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
...
</VisualState.Setters>
</VisualState>
<VisualState x:Name="VisualStateNormal">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="720" />
</VisualState.StateTriggers>
<VisualState.Setters>
...
</VisualState.Setters>
</VisualState>
<VisualState x:Name="VisualStateWide">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="1000" />
</VisualState.StateTriggers>
<VisualState.Setters>
...
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
查看模型:
public void ViewStateChanged(object sender, VisualStateChangedEventArgs args)
{
if(args.NewState.Name == "VisualStateNarrow")
{
isNarrowState = true;
}
...
}
我发现如何做到这一点的唯一方法是同时使用代码隐藏。换句话说,也没有找到真正的 MVVM 方式。
但是由于我使用的是 x:Bind,我已经在代码后面有一个 属性 到视图模型......所以使用它很容易。
要使其正常工作,您需要使用以下代码,请注意,我也将 VisualStateManager 的 CurrentStateChanged link 代码隐藏到 OnCurrentStateChanged 方法。
public sealed partial class MainPage : Page
{
private IViewModel ViewModel => DataContext as IViewModel;
public MainPage()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
UpdateVisualState(VisualStateGroup.CurrentState);
}
private void UpdateVisualState(VisualState currentState)
{
ViewModel.CurrentState = currentState;
}
private void OnCurrentStateChanged(object sender, VisualStateChangedEventArgs e)
{
UpdateVisualState(e.NewState);
}
}
我的网格具有三个不同的 VisualState。我如何将此信息绑定到我的视图模型,因为我需要根据视图状态做不同的事情。
现在我正在使用 CurrentStateChanged 事件(这不是很 mvvm 的方式)但主要问题是打开应用程序时不会触发该事件,所以我不知道初始视觉状态。
我目前的看法:
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="AdaptiveVisualStateGroup" CurrentStateChanged="{x:Bind ViewModel.ViewStateChanged, Mode=OneWay}">
<VisualState x:Name="VisualStateNarrow">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
...
</VisualState.Setters>
</VisualState>
<VisualState x:Name="VisualStateNormal">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="720" />
</VisualState.StateTriggers>
<VisualState.Setters>
...
</VisualState.Setters>
</VisualState>
<VisualState x:Name="VisualStateWide">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="1000" />
</VisualState.StateTriggers>
<VisualState.Setters>
...
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
查看模型:
public void ViewStateChanged(object sender, VisualStateChangedEventArgs args)
{
if(args.NewState.Name == "VisualStateNarrow")
{
isNarrowState = true;
}
...
}
我发现如何做到这一点的唯一方法是同时使用代码隐藏。换句话说,也没有找到真正的 MVVM 方式。 但是由于我使用的是 x:Bind,我已经在代码后面有一个 属性 到视图模型......所以使用它很容易。
要使其正常工作,您需要使用以下代码,请注意,我也将 VisualStateManager 的 CurrentStateChanged link 代码隐藏到 OnCurrentStateChanged 方法。
public sealed partial class MainPage : Page
{
private IViewModel ViewModel => DataContext as IViewModel;
public MainPage()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
UpdateVisualState(VisualStateGroup.CurrentState);
}
private void UpdateVisualState(VisualState currentState)
{
ViewModel.CurrentState = currentState;
}
private void OnCurrentStateChanged(object sender, VisualStateChangedEventArgs e)
{
UpdateVisualState(e.NewState);
}
}