程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 通過WPF綁定的ListBox獲取ListBoxItem及GoToState應用

通過WPF綁定的ListBox獲取ListBoxItem及GoToState應用

編輯:關於.NET

現公司項目中需要制作一個扇形菜單,菜單項是用ListBox重寫Style實現的,其數據是綁定的。菜單的每一項都有Normal,MouseOver和Selected三種狀態,這三種狀態當然可以通過鼠標移動和點擊控制,但現在要通過代碼來改變控件外觀實現三種狀態切換,該如何處理呢?

1.WPF綁定的ListBox獲取ListBoxItem

WPF中如果ListBox的ItemSource為綁定的,則ListBox.Items為綁定的數據源,而非ListBoxItem。如果直接通過如下代碼會發現無法獲取ListBoxItem:

var listBoxItem = ListBox1.Items[0] as List1BoxItem;

這時提示listBoxItem為null,那該如何獲取到ListBoxItem呢?這時就用到了ItemContainerGenerator.ContainerFromIndex(int index)方法,該方法返回對應於 System.Windows.Controls.ItemCollection 中指定索引項的元素:

var listBoxItem = ListBox1.ItemContainerGenerator.ContainerFromIndex(0) as FrameworkElement;

這次就獲取到了ListBox1中第一個listBoxItem。

2.WPF中的手動控制控件外觀變化

如何在不移動鼠標的情況下觸發ListBoxItem的MouseOver狀態發生呢?這時就利用到了VisualStateManager.GoToState(FrameworkElement control, string stateName, bool useTransitions)方法。該方法可以使控件在兩個狀態間隨意轉換:

首先,為項目中的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" TextWrapping="Wrap" Text="{TemplateBinding Content}" VerticalAlignment="Center" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

為ListBox1應用樣式,綁定數據源,拖出兩個button分別用於設置ListBoxItem的狀態:

<Grid>
        <ListBox x:Name="ListBox1" HorizontalAlignment="Left" Height="100" Margin="57,45,0,0" VerticalAlignment="Top" Width="100" ItemsSource="{Binding MenuList}" ItemContainerStyle="{DynamicResource ListBoxItemStyle1}" d:LayoutOverrides="HorizontalAlignment, VerticalAlignment" />
        <Button x:Name="btnMouseOver" Content="MouseOver" HorizontalAlignment="Left" Margin="75,0,0,65.163" VerticalAlignment="Bottom" Width="75" Click="btnMouseOver_Click" />
        <Button x:Name="btnNormal" Content="Normal" Margin="213,0,221,65.163" VerticalAlignment="Bottom" Click="btnNormal_Click" />
    </Grid>

後台找到ListBoxItem並改變其外觀:

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

效果:

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved