简体   繁体   中英

Bind VisualStateManager VisualState to view model?

I have Grid with three different VisualState's. How would I bind this info to my view model as I need to do thing differently depending on view state.

Right now Im using CurrentStateChanged event (which is not very mvvm way) but the major issue is that the event is not fired when the app is opened, so I do not know the initial visual state.

My current view:

<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>

View model:

public void ViewStateChanged(object sender, VisualStateChangedEventArgs args)
{
    if(args.NewState.Name == "VisualStateNarrow")
    {
        isNarrowState = true;
    }
    ...
}

The only way I found how to do this is by also using code behind. In other words not found a real MVVM way either. But due to the fact I'm using x:Bind, I already have a property to the viewmodel in code behind too... so using that is easy.

To get it working correctly you'll need to use following code, note that I link the CurrentStateChanged of the VisualStateManager to the OnCurrentStateChanged method in code behind too.

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);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM