在Windows Phone 8 Silverlight应用程序中,当我的ViewModel属性发生更改时,我使用DataStateBehavior
以不同的样式显示数据绑定列表项。问题是在ViewModel的构造函数中设置了Question中的属性。现在加载ListBox
时,它进入无限循环,导致堆栈溢出。
<ListBox ItemsSource="{Binding Trips}"
HorizontalContentAlignment="Stretch"
SelectionMode="Multiple">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Background"
Value="Transparent" />
<Setter Property="BorderThickness"
Value="0" />
<Setter Property="BorderBrush"
Value="Transparent" />
<Setter Property="Padding"
Value="0" />
<Setter Property="HorizontalContentAlignment"
Value="Stretch" />
<Setter Property="VerticalContentAlignment"
Value="Top" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="LayoutRoot"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver" />
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background"
Storyboard.TargetName="LayoutRoot">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{StaticResource TransparentBrush}" />
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation Duration="0"
To=".5"
Storyboard.TargetProperty="Opacity"
Storyboard.TargetName="ContentContainer" />
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Unselected" />
<VisualState x:Name="Selected" />
</VisualStateGroup>
<VisualStateGroup x:Name="BackEndStates">
<VisualState x:Name="IsNormal" />
<VisualState x:Name="IsSelected">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground"
Storyboard.TargetName="ContentContainer">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{StaticResource PhoneAccentBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentControl x:Name="ContentContainer"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
Foreground="{TemplateBinding Foreground}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" />
<i:Interaction.Behaviors>
<ec:DataStateBehavior Binding="{Binding IsSelected}"
Value="True"
TrueState="IsSelected"
FalseState="IsNormal" />
</i:Interaction.Behaviors>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Tap">
<ec:CallMethodAction TargetObject="{Binding}"
MethodName="ToggleIsSelected" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding TripName, Mode=OneWay}" />
<TextBlock Text="{Binding StartTime, Mode=OneWay}"
Grid.Row="1" />
<Line Height="1"
Grid.Row="2"
Stroke="{StaticResource PhoneAccentBrush}"
Fill="{StaticResource PhoneAccentBrush}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
如您所见,我删除了原始Selected状态的StoryBoard
。我有一组新的视觉状态,由DataStateBehavior
触发。
现在当我尝试运行它时,我在尝试渲染列表框时得到了一个stackoverflow。堆栈帧充满了这种模式。看起来当DataStateBehavior
设置状态时,它会触发应用模板,并重复整个评估周期。
[Managed to Native Transition]
System.Windows.ni.dll!MS.Internal.XcpImports.FrameworkElement_ApplyTemplate(System.Windows.FrameworkElement frameworkElement) Unknown
System.Windows.ni.dll!System.Windows.Controls.Control.ApplyTemplate() Unknown
microsoft.expression.interactions.DLL!Microsoft.Expression.Interactivity.VisualStateUtilities.GoToState(System.Windows.FrameworkElement element, string stateName, bool useTransitions) Unknown
microsoft.expression.interactions.DLL!Microsoft.Expression.Interactivity.Core.DataStateBehavior.Evaluate() Unknown
microsoft.expression.interactions.DLL!Microsoft.Expression.Interactivity.Core.DataStateBehavior.OnBindingChanged(System.Windows.DependencyObject obj, System.Windows.DependencyPropertyChangedEventArgs args) Unknown
System.Windows.ni.dll!System.Windows.DependencyObject.RaisePropertyChangeNotifications(System.Windows.DependencyProperty dp, object oldValue, object newValue) Unknown
System.Windows.ni.dll!System.Windows.DependencyObject.UpdateEffectiveValue(System.Windows.DependencyProperty property, System.Windows.EffectiveValueEntry oldEntry, ref System.Windows.EffectiveValueEntry newEntry, System.Windows.DependencyObject.ValueOperation operation) Unknown
System.Windows.ni.dll!System.Windows.DependencyObject.RefreshExpression(System.Windows.DependencyProperty dp) Unknown
System.Windows.ni.dll!System.Windows.Data.BindingExpression.SendDataToTarget() Unknown
System.Windows.ni.dll!System.Windows.Data.BindingExpression.SourceAcquired() Unknown
System.Windows.ni.dll!System.Windows.Data.BindingExpression.System.Windows.IDataContextChangedListener.OnDataContextChanged(object sender, System.Windows.DataContextChangedEventArgs e) Unknown
System.Windows.ni.dll!System.Windows.WeakDataContextChangedListener.MentorDataContextChanged(object sender, System.Windows.DataContextChangedEventArgs e) Unknown
System.Windows.ni.dll!System.Windows.FrameworkElement.OnDataContextChanged(System.Windows.DataContextChangedEventArgs e) Unknown
System.Windows.ni.dll!System.Windows.FrameworkElement.OnTreeParentUpdated(System.Windows.DependencyObject newParent, bool bIsNewParentAlive) Unknown
System.Windows.ni.dll!System.Windows.DependencyObject.UpdateTreeParent(MS.Internal.IManagedPeer oldParent, MS.Internal.IManagedPeer newParent, bool bIsNewParentAlive, bool keepReferenceToParent) Unknown
System.Windows.ni.dll!MS.Internal.FrameworkCallbacks.ManagedPeerTreeUpdate(System.IntPtr oldParentElement, System.IntPtr parentElement, System.IntPtr childElement, byte bIsParentAlive, byte bKeepReferenceToParent, byte bCanCreateParent) Unknown
[Native to Managed Transition]
有人能想出一种防止这种无限循环的方法吗?
答案 0 :(得分:0)
好的,事实证明这是.Net现在的另一个特质,documentation还不够清楚,并留下了很多“弄明白”。经过大量的试验,我发现如果绑定值在加载时为null,则行为有效。所以我最终将我的属性更改为bool?
(Nullable bool)而不是简单bool
,在构造函数中将其设置为Null,并实现延迟加载逻辑以设置为true / false。现在它不会导致StackOverFLow。
如果有人想尝试一下,请使用http://1drv.ms/1D8l6yS中的示例项目,它既有问题版本也有固定版本。