WPF之VirtualizingStackPanel.IsVirtualizing="False"
原文:WPF之VirtualizingStackPanel.IsVirtualizing="False"
相信从winform转到wpf的人都遇到过这样的困惑,在处理DataGrid时,我想让某一单元格根据格式校验的不同情况显示不同的颜色,以便于用户区分。
于是你去查找各种资料,wpf下DataGrid如何改变某一单元格颜色,如果运气不好,可能搜索到的结果会令你失望,运气不错的话你会搜到类似如下代码:
private void changeCell()
{
this.sj_DataGrid.Dispatcher.Invoke(
new Action(
delegate
{
foreach (LSErr l in lse)
{
for (int i = 0; i < this.sj_DataGrid.Items.Count; i++)
{
DataRowView drv = this.sj_DataGrid.Items[i] as DataRowView;
DataGridRow row = (DataGridRow)this.sj_DataGrid.ItemContainerGenerator.ContainerFromIndex(i); if (drv["StockCode"].ToString()==l.stCode)
{
System.Windows.Controls.Primitives.DataGridCellsPresenter presenter = GetVisualChild<System.Windows.Controls.Primitives.DataGridCellsPresenter>(row);
if (presenter != null)
{
DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(l.ci);
cell.Background = new SolidColorBrush(Colors.CadetBlue);
}
break;
}
}
}
}
)
);
}
//获取单元格
public static T GetVisualChild<T>(Visual parent) where T : Visual
{ T childContent = default(T);
if (parent != null)
{
int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < numVisuals; i++)
{
Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
childContent = v as T;
if (childContent == null)
{
childContent = GetVisualChild<T>(v);
}
if (childContent != null)
{
break;
}
}
//Thread.Sleep(10);
}
return childContent;
}
看起来很不错,而且运行也能成功。
不过很快你就会发现问题,那就是当你的窗口大小变化时,或者你拖动滚动条的时候奇葩的事情发生了,你选择变色的单元格变掉了,变色的可能是任何一个单元格,反正不是你想要的那一个。
于是你又再一次踏上了搜索之旅
终于让你找到了一个解决办法,就是我们标题中的VirtualizingStackPanel.IsVirtualizing="False",不错,效果很好,DataGrid应用这一属性之后我们可以准确的改变单元格颜色了。
但是,问题又来了...
当你的DataGrid加载的数据稍微多一些时,比如2000,3000,...10000...,再次运行你的程序你会发现主界面竟然卡住了好几秒,于是你设置断点查看,运行时间。你会发现由于ui虚拟化被禁用,数据加载的时间被无限拖长。用户界面卡顿,造成短时间内无响应,给用户死机的感受(PS:实际上此时程序正在玩儿命的绘制UI)
这种情况下,纵使你数据校验再好,数据校验整个过程中程序卡死的假象蒙蔽下,用户也会失去耐心,除非你的项目经理很强势,让用户耐心等待...
So,换一种实现策略吧
最终,还是暂时使用模板类中的触发器来实现吧,当不同的属性下生成不同的颜色
<Window.Resources>
<!--<c:ErrorConverter x:Key="ErrorConverter"/>-->
<c:SheetArr x:Key="SheetCols"/>
<Style TargetType="{x:Type Button}" x:Key="highlightStyle"> <Style.Triggers> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Background" Value="#EEEEEE" /> </Trigger> <MultiTrigger> <MultiTrigger.Conditions>
<Condition Property="IsEnabled" Value="true" /> </MultiTrigger.Conditions> <Setter Property="BorderBrush" Value="Red"/> <Setter Property="FontSize" Value="14" /> <Setter Property="FontWeight" Value="Bold" /> <Setter Property="Foreground" Value="Red" /> </MultiTrigger> </Style.Triggers> </Style>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding State}" Value="格式错误">
<Setter Property="ToolTip">
<Setter.Value>
<ToolTip>
<TextBlock Text="{Binding State,StringFormat='错误:{0}'}"/>
</ToolTip>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style> </Window.Resources>
这只是一种过度方案,当发现某单元格值达到某种条件时改变背景色,不够灵活,真正的解决这一问题还得研究wpf的ui visualization实现上下手
希望已经碰到这种问题的兄弟少走点儿弯路,或者如果有大神已经解决这种问题还请指教
WPF之VirtualizingStackPanel.IsVirtualizing="False"的更多相关文章
- WPF疑难杂症会诊
原文:WPF疑难杂症会诊 为什么图片像素是模糊的? 容器边框设为非整数时,其内容中的像素图片会产生模糊,即使设置SnapsToDevicePixels="True"也无效. 以下是 ...
- 用WPF实现在ListView中的鼠标悬停Tooltip显示
原文:用WPF实现在ListView中的鼠标悬停Tooltip显示 一.具体需求描述 在WPF下实现,当鼠标悬停在ListView中的某一元素的时候能弹出一个ToolTip以显示需要的信息. 二.代码 ...
- DataGrid当列宽超出当前宽度时,没有数据也恒有滚动条
附件是DataGrid支持滚动条的文件. 具体使用如下: 1)DataGrid使用控件模板 <Setter Property="Template" Value="{ ...
- DataGrid 显示选中的item
Datagrid或者listview 中想要把相应的项 滚动到当前可见的位置, 必须满足2个条件: 1) 必须去掉虚拟化 VirtualizingStackPanel.IsVirtualiz ...
- comobox在datagrid里,当滚动scrollbar时,会导致comobox选中项被重置的解决办法
VirtualizingStackPanel.IsVirtualizing="False"
- WPF自定义控件与样式(6)-ScrollViewer与ListBox自定义样式
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Scr ...
- WPF自定义控件与样式(7)-列表控件DataGrid与ListView自定义样式
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Dat ...
- WPF自定义控件与样式(9)-树控件TreeView与菜单Menu-ContextMenu
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 菜单M ...
- WPF自定义控件与样式(12)-缩略图ThumbnailImage /gif动画图/图片列表
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要针对WPF项目 ...
随机推荐
- Go语言学习(十)bytes包处理字节切片
bytes包提供了对字节切片进行读写操作的一系列函数 字节切片处理的函数比較多,分为基本处理函数,比較函数,后缀检查函数,索引函数,切割函数, 大写和小写处理函数和子切片处理函数等. 1.字节切片基本 ...
- HTML5移动开发实战必备知识——本地存储(1)
本地缓存是HTML5出现的新技术,这个技术的出现使得移动web的开发成为了可能.我们都知道.要想打造一个高性能的移动应用,速度是关键.而在HTML5之前.仅仅有cookie可以存储数据,大小仅仅有4k ...
- Hudson版本控制 (备注)
http://www.ttlsa.com/tools/install-hudson-on-linux/
- 【codeforces 768A】Oath of the Night's Watch
[题目链接]:http://codeforces.com/contest/768/problem/A [题意] 让你统计这样的数字x的个数; x要满足有严格比它小和严格比它大的数字; [题解] 排个序 ...
- CocoaPods停在Analyzing dependencies的解决方案
解决办法: 1: 换镜像索引库 国内有人建立了cocoapods的索引库镜像,可以通过如下命令更改镜像: pod repo remove master pod repo add master htt ...
- WPF入门(四)->线形区域Path内容填充之填充图(ImageBrush)
原文:WPF入门(四)->线形区域Path内容填充之填充图(ImageBrush) 前面我们提到了LinearGradientBrush可以用来画渐变填充图,那么我们同时也可以使用ImageBr ...
- sparksql json 合并json数据
java public class Demo { private static SparkConf conf = new SparkConf().setAppName("demo" ...
- Spring异步方法注解 @Async
@Async 0. 介绍 在Spring 3.x之后,通过内置@Async标明异步方法,可以简化异步开发流程. @Async既可提供无返回值的调用,也可提供有返回值的调用,下文将分别介绍两种使用方式. ...
- asp.net中c#求百分比
double m= 50;double n= 100; Response.Write((m/ (m+ n)).ToString("0%"));Response.Write((m/ ...
- Cocos2d-X中国象棋的发展《五岁以下儿童》摆棋
在博客上,以实现创建的游戏场景.而一些button,因为button落实到事件作出详细答复,需要使用一些功能摆棋.为此我特意button上的背面的具体实施, 在摆棋前先理清一下摆棋的思路: 1.创建一 ...