zoukankan      html  css  js  c++  java
  • WPF绑定的ListBox获取ListBoxItem及GoToState应用

    现公司项目中需要制作一个扇形菜单,菜单项是用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);
            }

    效果:

  • 相关阅读:
    Head first javascript(七)
    Python Fundamental for Django
    Head first javascript(六)
    Head first javascript(五)
    Head first javascript(四)
    Head first javascript(三)
    Head first javascript(二)
    Head first javascript(一)
    Sicily 1090. Highways 解题报告
    Python GUI programming(tkinter)
  • 原文地址:https://www.cnblogs.com/infly123/p/3871969.html
Copyright © 2011-2022 走看看