我需要更改列表框项目的可视状态。这是具有视觉状态的DataTemplate。我正在使用WP7作为我的环境。
<DataTemplate x:Key="MessageItemTemplate">
<Grid MinWidth="200" MinHeight="90" Width="460" Margin="0,2">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="Modes">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0" To="Normal">
<Storyboard>
<DoubleAnimation Duration="0:0:0.4" To="0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="border" d:IsOptimized="True"/>
</Storyboard>
</VisualTransition>
<VisualTransition GeneratedDuration="0"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal"/>
<VisualState x:Name="Edit">
<Storyboard>
<DoubleAnimation Duration="0:0:0.7" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="border" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<VisualStateManager.CustomVisualStateManager>
<ic:ExtendedVisualStateManager/>
</VisualStateManager.CustomVisualStateManager>
<StackPanel Orientation="Vertical" d:LayoutOverrides="Width, Height" Canvas.ZIndex="10" Margin="7">
<TextBlock x:Name="tbTitle" Text="{Binding Path=Title, Mode=OneWay}" FontSize="24" VerticalAlignment="Top" Foreground="{StaticResource PhoneContrastBackgroundBrush}" FontWeight="Bold" Height="30" FontFamily="Microsoft New Tai Lue"/>
<TextBlock x:Name="tbMessage" Text="{Binding Path=Message, Mode=OneWay}" FontSize="29.333" Foreground="{StaticResource PhoneContrastBackgroundBrush}" Margin="0" FontFamily="Candara" TextWrapping="Wrap" HorizontalAlignment="Left"/>
</StackPanel>
<Border BorderBrush="{StaticResource PhoneAccentBrush}" BorderThickness="2" Background="{StaticResource PhoneBackgroundBrush}" CornerRadius="10" />
<Border x:Name="border" BorderThickness="4" CornerRadius="4" BorderBrush="#FFED1212" Opacity="0" >
<Grid>
<Path Data="M149,0.16666667 L192,36.166332 L189.60141,-2.7298894 z" Fill="#FFED1212" HorizontalAlignment="Right" Margin="0,-3.031,-2.784,38.328" Stretch="Fill" UseLayoutRounding="False" Width="51.629" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<CompositeTransform Rotation="2.523" TranslateX="-0.076551587038494961" TranslateY="-0.0016857129841283403"/>
</Path.RenderTransform>
</Path>
<Image Margin="0" Source="images/pensil.png" Stretch="Fill" Height="26" Width="26" HorizontalAlignment="Right" VerticalAlignment="Top"/>
</Grid>
</Border>
</Grid>
</DataTemplate>
继承我的ListBox:
<ListBox x:Name="SmsMessagesList" Grid.Row="1"
ItemsSource="{Binding Path=Model.Messages}"
SelectionChanged="SmsMessagesList_SelectionChanged"
ItemTemplate="{StaticResource MessageItemTemplate}">
</ListBox>
我绑定到此ListBox的ItemsSource的ObservableCollection是:
public ObservableCollection<SmsMessage> Messages;
public class SmsMessage : EntityBase
{
private string _CurrentState;
public string CurrentState
{
get
{
return _CurrentState;
}
set
{
_CurrentState = value;
PropertyChangedHandler("CurrentState");
}
}
private string _Title;
public string Title
{
get
{
return _Title;
}
set
{
_Title = value;
PropertyChangedHandler("Title");
}
}
private string _Message;
public string Message
{
get
{
return _Message;
}
set
{
_Message = value;
PropertyChangedHandler("Message");
}
}
}
如何根据属性'CurrentState'更改将ListBox的视觉状态更改为'Edit'和'Normal'?
由于
答案 0 :(得分:3)
如果您想坚持使用绑定方法,那么您唯一真正的选择就是Blend Behavior。但是,由于Silverlight 3(以及WP7)不支持数据绑定行为属性,因此您的路径要复杂得多。是的,这是一个PITA,是的,我希望他们下周将在MIX宣布SL4功能。
下面是一个 WPF 行为,它可以做同样的事情,让您了解行为所需的内容,但在Silverlight 3中不起作用 WP7由于上述问题。您需要将State
属性更改为Binding
类型,并完成访问该绑定值的复杂过程。您可以在Patterns & Practices WP7 Dev Guide source的TailSpin.PhoneClient.Infrastructure.ButtonCommand
或MVVM Light's EventToCommand中查看如何执行此操作的示例。
public class StateManagementBehavior : Behavior<FrameworkElement>
{
public static readonly DependencyProperty StateProperty =
DependencyProperty.Register("State", typeof(string),
typeof(StateManagementBehavior),
new UIPropertyMetadata(null, PropertyChangedCallback));
public static readonly DependencyProperty UseTransitionsProperty =
DependencyProperty.Register("UseTransitions", typeof(bool),
typeof(StateManagementBehavior),
new UIPropertyMetadata(true));
public static void PropertyChangedCallback(
DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var stateManagementBehavior = (StateManagementBehavior)d;
stateManagementBehavior.GoToState();
}
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Loaded += (s, e) => GoToState();
}
private void GoToState()
{
if (AssociatedObject == null || State == null) return;
VisualStateManager.GoToState(AssociatedObject, State, UseTransitions);
}
public string State
{
get { return (string)GetValue(StateProperty); }
set { SetValue(StateProperty, value); }
}
public bool UseTransitions
{
get { return (bool)GetValue(UseTransitionsProperty); }
set { SetValue(UseTransitionsProperty, value); }
}
}
假设您完成所有工作,您将使用以下行为:
<DataTemplate x:Key="MessageItemTemplate">
<Grid MinWidth="200" MinHeight="90" Width="460" Margin="0,2">
<i:Interactivity.Behaviors>
<infrastructure:StateManagementBehavior State="{Binding CurrentState}"
UseTransitions="True" />
</i:Interactivity.Behaviors>
<VisualStateManager.VisualStateGroups>
...
</VisualStateManager.VisualStateGroups>
...
</Grid>
</DataTemplate>
答案 1 :(得分:1)
如果您提供控件作为列表框项目的容器。然后,您可以使用VisualStateManage.GoToState(this, "Your State", true);
答案 2 :(得分:0)
刚刚设法在SL4项目中发生这种情况我正在工作(所以不确定它是否适用于WP7,但原始库是为SL3制作的,所以它应该),解决方案是使用{{1来自DataTemplate中的Expression Blend Samples on CodePlex:
DataStateBehavior
如果您需要超过2个州,还可以使用<i:Interaction.Behaviors>
<ei:DataStateBehavior Binding="{Binding IsEditMode}" Value="True" TrueState="Edit" FalseState="Normal"/>
</i:Interaction.Behaviors>
。