0

我需要更改我的列表框项目的视觉状态。这里是具有视觉状态的DataTemplate。我使用WP7作为我的环境。在WP7 + Silverlight中,如何更改ListBox项目的视觉状态?

<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 x:Name="SmsMessagesList" Grid.Row="1" 
       ItemsSource="{Binding Path=Model.Messages}" 
       SelectionChanged="SmsMessagesList_SelectionChanged" 
       ItemTemplate="{StaticResource MessageItemTemplate}"> 
     </ListBox> 

的的ObservableCollection我绑定到这个ListBox的的ItemsSource是:

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

我怎样才能改变我的ListBox的可视状态为 '编辑'和'正常'基于属性'CurrentState'的变化?

谢谢

回答

1

如果您提供一个控件作为您的列表框项目的容器。然后,您可以将用于更改状态的逻辑添加到该控件的代码中使用VisualStateManage.GoToState(this, "Your State", true);

3

如果您想坚持绑定方式,那么您唯一的实际选择是Blend Behavior。但是,由于Silverlight 3(以及WP7)不支持数据绑定行为属性,因此您的路径要复杂得多。是的,这是一个PITA,是的,我希望他们下周将在MIX上宣布SL4的功能。

下面是一个WPF行为做同样的事,给你由行为需要什么样的想法,但它不会在Silverlight 3/WP7由于上述问题的工作。您需要将State属性更改为Binding类型,然后通过访问该绑定值的复杂过程。您可以在Patterns & Practices WP7 Dev Guide sourceTailSpin.PhoneClient.Infrastructure.ButtonCommandMVVM 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> 
+0

实际上问题不在于绑定,它相对容易用简单的附加属性来解决,但VisualStateManager.GoToState令人讨厌地只将一个控件作为目标,所以它无法使用根网格工作: ( – dain 2011-04-07 16:20:10

0

好不容易才坐上SL4项目发生这种情况,我的工作(所以不知道,如果它是打算在WP7工作,但原来的库是为SL3作出所以它应该),该解决方案是使用DataStateBehaviorExpression Blend Samples on CodePlex中的DataTemplate内:

<i:Interaction.Behaviors> 
    <ei:DataStateBehavior Binding="{Binding IsEditMode}" Value="True" TrueState="Edit" FalseState="Normal"/> 
</i:Interaction.Behaviors> 

如果您需要超过2个州,则还可以使用DataStateSwitchBehavior

相关问题