根据视图模型

时间:2015-10-05 09:40:24

标签: xaml mvvm windows-phone-8.1 windows-8.1 mvvm-light

我对MVVM很新,所以我认为这是基础知识。它是一个带有MVVM灯和Sqlite DB的Windows 8.1应用程序。

我有一个包含4个州的页面。每个状态都包含一个GridView,您可以在其中选择要设置绑定属性的项目。在SelectionChanged上,我去了下一个州。

这是GridView的xaml:

 <GridView Grid.Row="1" Grid.Column="1" ItemsSource="{Binding Essences}" SelectedItem="{Binding SelectedEssense,Mode=TwoWay}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" x:Name="EssenceGridView" Opacity="0" >
        <Interactivity:Interaction.Behaviors>
            <Core:EventTriggerBehavior EventName="SelectionChanged">
                <Core:GoToStateAction StateName="Diametre"/>
            </Core:EventTriggerBehavior>
        </Interactivity:Interaction.Behaviors>
        <GridView.ItemTemplate>
            <DataTemplate >
                <Grid Width="250" Height="80">
                    <TextBlock Text="{Binding Trigramme}" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
                </Grid>
            </DataTemplate>
        </GridView.ItemTemplate>
    </GridView>

改变状态的StoryBoards只是不透明度的改变。

现在我希望能够完全跳过一个状态,因为用户希望能够使用某些默认属性(因此他不必一直选择相同的属性) 因此,如果在我的ViewModel中设置了默认属性,我希望能够跳过一个状态。 在MVVM中实现这一目标的最佳方法是什么?

编辑:借助Depechie的链接,我成功地将我的VisualState绑定到我的ViewModel中的属性。我不得不更新代码,因为它是用于Windows Phone 8而我正在使用Windows 8.1 !!

这里更新的课程: BindVisualStateBehaviorHandler.cs

class BindVisualStateBehaviorHandler : Behavior<FrameworkElement>
{
    //
    // Dependency property "StateName" that you can bind in Blend.
    // Bind this to the enumeration that controls the visual state.
    //
    public static DependencyProperty StateNameProperty = DependencyProperty.Register(
        "StateName",
        typeof(string),
        typeof(BindVisualStateBehaviorHandler),
        new PropertyMetadata(null, StateNamePropertyChanged));

    public string StateName
    {
        get { return (string)GetValue(StateNameProperty); }
        set { SetValue(StateNameProperty, value); }
    }

    //
    // When the StateName property changes, switch to the
    // new visual state, and play transition animations.
    //
    private static void StateNamePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        ((BindVisualStateBehaviorHandler)obj).UpdateVisualState(
            (string)args.NewValue,
            useTransitions: true);
    }

    //
    // When the behavior is first attached, go to the visual state,
    // but don't play any animations.
    //
    protected override void OnAttached()
    {
        UpdateVisualState(
            StateName,
            useTransitions: false);
        base.OnAttached();
    }

    private void UpdateVisualState(string visualState, bool useTransitions)
    {
        if (AssociatedObject != null)
        {
            if (VisualStateUtilities.FindNearestStatefulControl(base.AssociatedObject as FrameworkElement) != null)
            {
                VisualStateUtilities.GoToState(
                    VisualStateUtilities.FindNearestStatefulControl(base.AssociatedObject as FrameworkElement),
                    visualState,
                    useTransitions);
            }
        }
    }
}

我不得不使用自己的行为,因为它在Microsoft.Xaml.Interactivity中没有出现

Behavior.cs

 public abstract class Behavior<T> : DependencyObject, IBehavior where T : DependencyObject
{
    //http://reflectionit.nl/Blog/2013/windows-8-xaml-tips-creating-blend-behaviors

    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    public T AssociatedObject { get; set; }

    protected virtual void OnAttached()
    {
    }

    protected virtual void OnDetaching()
    {
    }

    public void Attach(Windows.UI.Xaml.DependencyObject associatedObject)
    {
        this.AssociatedObject = (T)associatedObject;
        OnAttached();
    }

    public void Detach()
    {
        OnDetaching();
    }

    DependencyObject IBehavior.AssociatedObject
    {
        get { return this.AssociatedObject; }
    }
}

然后在我的视图中:

 <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="AppStates" >
            <VisualStateGroup.Transitions>
                <VisualTransition GeneratedDuration="0:0:0.2"/>
            </VisualStateGroup.Transitions>
            <VisualState x:Name="SaisieTige" >
                ...
            <VisualState x:Name="Diametre">
                ...
            </VisualState>
            <VisualState x:Name="Hauteur">
               ...
            </VisualState>
            <VisualState x:Name="Resume">
                ...
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    <Interactivity:Interaction.Behaviors>
        <Behavior:BindVisualStateBehaviorHandler x:Name="AppStateBehavior" StateName="{Binding StateHandler.AppState,Mode=TwoWay}"></Behavior:BindVisualStateBehaviorHandler>
        <Core:EventTriggerBehavior EventName="Loaded">
            <Core:InvokeCommandAction Command="{Binding SelectEssenceOrNotCommand}"></Core:InvokeCommandAction>
        </Core:EventTriggerBehavior>
    </Interactivity:Interaction.Behaviors>

每次改变状态时我都要调用RaisePropertyCHange:

 StateHandler.SetAppState(AppStates.SaisieTige);
 RaisePropertyChanged("StateHandler");

现在它正在发挥作用,很多人!!!“

0 个答案:

没有答案