现公司项目中需要制作一个扇形菜单,菜单项是用ListBox重写Style实现的,其数据是绑定的。菜单的每一项都有Normal,MouseOver和Selected三种状态,这三种状态当然可以通过鼠标移动和点击控制,但现在要通过代码来改变控件外观实现三种状态切换,该如何处理呢?

 
1.WPF绑定的ListBox获取ListBoxItem
 
WPF中如果ListBox的ItemSource为绑定的,则ListBox.Items为绑定的数据源,而非ListBoxItem。如果直接通过如下代码会发现无法获取ListBoxItem: 
var listBoxItem = ListBox1.Items[] as List1BoxItem;

这时提示listBoxItem为null,那该如何获取到ListBoxItem呢?这时就用到了ItemContainerGenerator.ContainerFromIndex(int index)方法,该方法返回对应于 System.Windows.Controls.ItemCollection 中指定索引项的元素:

var listBoxItem = ListBox1.ItemContainerGenerator.ContainerFromIndex() 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() as FrameworkElement;
VisualStateManager.GoToState(item, "MouseOver", false);
} private void btnNormal_Click(object sender, RoutedEventArgs e)
{
var item = ListBox1.ItemContainerGenerator.ContainerFromIndex() as FrameworkElement;
VisualStateManager.GoToState(item, "Normal", false);
}

效果:

WPF绑定的ListBox获取ListBoxItem及GoToState应用的更多相关文章

  1. WPF ListBox 获取listBoxItem

    1.已知item的DataContext,获取ListBoxItem 1)ItemContainerGenerator.ContainerFromItem var selectedItem = Doc ...

  2. WPF,解决Listbox,按住ListboxItem向下拖出Listbox,横向滚动条跑到最后。

    类似这种样式的控件,.,在横向滚动条隐藏的情况下有这样的问题.(横向滚动条显示的时候也会,,目前不知道怎么解决.) 因为这个控件偏移是利用ListBox的ItemsPanelTemplate模版里的S ...

  3. 获取listboxitem在ListBox中的index并转换成abcd

    原文 获取listboxitem在ListBox中的index并转换成abcd 截图如下: 1.实现Converter  获取到listbox,并得到listitem在listbox中的index p ...

  4. wpf之ListBox中ListBoxItem横向排列

    ListBox中ListBoxItem默认是纵向排列,可以通过自定义样式,让其横向排列, 如下Demo: XAML: <Window x:Class="ListBoxItemStyle ...

  5. WPF快速入门系列(4)——深入解析WPF绑定

    一.引言 WPF绑定使得原本需要多行代码实现的功能,现在只需要简单的XAML代码就可以完成之前多行后台代码实现的功能.WPF绑定可以理解为一种关系,该关系告诉WPF从一个源对象提取一些信息,并将这些信 ...

  6. WPF 简易手风琴 (ListBox+Expander)

    概述 之前听说很多大神的成长之路,几乎都有个习惯--写博文,可以有效的对项目进行总结.从而提高开发的经验.所以初学WPF的我想试试,顺便提高一下小学作文的能力.O(∩_∩)O哈哈~ 读万卷书不如行万里 ...

  7. wpf CollectionViewSource与ListBox的折叠、分组显示,及输入关键字 Filter的筛选

    在wpf中虽然ObservableCollection<T>作为ListBox的Itemsource,很好,很强大!但是CollectionViewSource与ListBox才是天作之合 ...

  8. WPF:自定义ListBox的选择样式

    首先介绍一种简单地方法:就是通过自定义SystemColors类的参数来自定义WPF ListBox选择颜色的, SystemColors的HighlightBrushKey和HighlightTex ...

  9. 解决WPF程序中ListBox ItemsSource变化时不重置ScrollBar的问题

    解决WPF程序中ListBox ItemsSource变化时不重置ScrollBar的问题 当我们改变ListBox的ItemsSource时,会发现这样一个问题:数据源变化时,虽然控件中的内容会跟着 ...

随机推荐

  1. (BestCoder Round #64 (div.2))Array

    BestCoder Round #64 (div.2) Array 问题描述 Vicky是个热爱数学的魔法师,拥有复制创造的能力. 一开始他拥有一个数列{1}.每过一天,他将他当天的数列复制一遍,放在 ...

  2. springMvc里的mvc:resources与静态资源的访问

    在进行Spring MVC的配置时,通常我们会配置一个dispatcher servlet用于处理对应的URL.配置如下:   <servlet>   <servlet-name&g ...

  3. SRM472

    这次是rng_58出的题目,思维难度还是相当大的的..很值得一做. 250pt: 题意:盒子里有n 个 potatoes,甲乙两个人,每次只能拿4的幂次方数(1,4,16...),最后不能拿的输.求谁 ...

  4. 11.js循环与函数

    Switch语句 Switch(变量){ : 如果变量和1的值相同,执行该处代码 break; : 如果变量和2的值相同,执行该处代码 break; : 如果变量和3的值相同,执行该处代码 break ...

  5. unigui导出EXCEL使用NATIVEEXCEL

    unigui导出EXCEL使用NATIVEEXCEL // 需要nativeexcel控件// cxg 2017-9-9 unit myExcel; interface uses System.Sys ...

  6. @requestParamore与@pathvariable的区别

    http://localhost:8080/Springmvc/user/page.do?pageSize=3&pageNow=2 你可以把这地址分开理解,其中问号前半部分:http://lo ...

  7. [LintCode] Longest Increasing Continuous subsequence

    http://www.lintcode.com/en/problem/longest-increasing-continuous-subsequence/# Give you an integer a ...

  8. node.js global object,util and so on

    核心模块主要内容: 全局对象 常用工具 事件机制 文件系统访问 http服务器和客户端 global object: 所有的全局变量(除了global本身外)都是global object 的属性(a ...

  9. Martin Fowler 分层测试概念博文分享

    在我们测试工作中,常常遇到这样的问题:开发与测试团队分属不同的不同(部门隔离.沟通不畅),质量职责划分不清(出现bug往往都是测试人员背锅),需求的不确定和易变性(需求不断变化导致代码不停更新.产品重 ...

  10. WPF Slider滑动条的颜色修改

    效果如下: 鄙人虽然开发WPF有些时间,但之前一直是一些简单Template和Style改改之类的工作,并没有深入研究过.此次为了完成工作,首先也是网上搜了半天,没有找到合适的代码直接拷贝(搜索能力待 ...