首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WPF 繫結 ListBox 取得 ListBoxItem 並透過 GoToState 程式化切換視覺狀態

     編輯:關於.NET

情境

ListBox 使用 ItemsSource 繫結資料,需在無滑鼠互動情況下,透過程式碼強制將特定項目切換至 MouseOver、Normal 等視覺狀態(如外部按鈕控制高亮)。

難點:ItemsSource 繫結時,ListBox.Items 為資料物件,非 ListBoxItem

// 錯誤示範:轉型失敗,回傳 null
var item = ListBox1.Items[0] as ListBoxItem;

解法:ItemContainerGenerator.ContainerFromIndex

// 正確取得視覺容器
var listBoxItem = ListBox1.ItemContainerGenerator.ContainerFromIndex(0) as FrameworkElement;

視覺狀態切換:VisualStateManager.GoToState

VisualStateManager.GoToState(control, stateName, useTransitions);
  • control:目標 FrameworkElement(此處為 ListBoxItem)。
  • stateName:視覺狀態名稱(需與 ControlTemplate 內 VisualState x:Name 一致)。
  • useTransitions:是否播放轉場動畫。

完整範例

1. 定義 ListBoxItem Style(含 Normal / MouseOver 狀態)

<Style x:Key="ListBoxItemStyle1" TargetType="{x:Type ListBoxItem}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                <Grid>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal">
                                <Storyboard>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="rectangle">
                                        <EasingColorKeyFrame KeyTime="0" Value="#FF5CFD30" />
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="rectangle">
                                        <EasingColorKeyFrame KeyTime="0" Value="#FF29B5B8" />
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Disabled" />
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Rectangle x:Name="rectangle" Fill="#FF5AFB2E" Stroke="Black" />
                    <TextBlock HorizontalAlignment="Center" Text="{TemplateBinding Content}" VerticalAlignment="Center" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

2. XAML 佈局

<Grid>
    <ListBox x:Name="ListBox1" ItemsSource="{Binding MenuList}" 
             ItemContainerStyle="{DynamicResource ListBoxItemStyle1}" />
    <Button x:Name="btnMouseOver" Content="MouseOver" Click="btnMouseOver_Click" />
    <Button x:Name="btnNormal" Content="Normal" Click="btnNormal_Click" />
</Grid>

3. 後端程式碼

private void btnMouseOver_Click(object sender, RoutedEventArgs e)
{
    var item = ListBox1.ItemContainerGenerator.ContainerFromIndex(2) as FrameworkElement;
    VisualStateManager.GoToState(item, "MouseOver", false);
}

private void btnNormal_Click(object sender, RoutedEventArgs e)
{
    var item = ListBox1.ItemContainerGenerator.ContainerFromIndex(2) as FrameworkElement;
    VisualStateManager.GoToState(item, "Normal", false);
}

效果展示

MouseOver 狀態 Normal 狀態

關鍵提醒

  1. ContainerFromIndex 若項目尚未虛擬化產生(未滾動到可視區),會回傳 null。需先 ListBox1.ScrollIntoView(dataItem) 強制產生容器。
  2. 視覺狀態名稱區分大小寫,必須與 ControlTemplate 完全一致。
  3. 適用於任何 ItemsControl 衍生類別(ComboBox, TreeView 等)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved