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

    效果:

  • 相关阅读:
    【SpringBoot】 理解SpringBoot的启动原理
    【SpringBoot】SpringBoot的基础,全面理解bean的生命周期
    【转】 Linux 命令解释(Linux基础二)
    【转】 Linux 的目录详解 (Linux基础一)
    【SpringBoot】 一种解决接口返回慢的方式
    【Jmeter基础】 Linux上运行Jmeter
    【SpingBoot】 测试如何使用SpringBoot搭建一个简单后台1
    单例模式@Singleton在测试中的运用
    性能测试基础 ---TCP通信过程的状态码与过程,以及出现错误码的分析(TIME_WAIT,CLOSE_WAIT)
    Spring5源码分析(007)——IoC篇之加载BeanDefinition总览
  • 原文地址:https://www.cnblogs.com/infly123/p/3871969.html
Copyright © 2011-2022 走看看