我对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");
现在它正在发挥作用,很多人!!!“