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

相關問題