更改 Silverlight DataGrid 中一个或多个列的背景色
Column.BackgroundColor = "Yellow"? 我希望如此。
引言
这是一件你认为应该很简单的事情,但事实并非如此,除非我遗漏了什么。我想写一个关于我如何得出解决方案的逐步说明,以防我走了比我需要的更艰难的道路,并且有人可以指出我错在哪里。
背景
这是 DataGrid
的基本 XAML 以及它在浏览器中的外观。您有排序、验证和双向绑定,这非常好
困境
所有这些都运行良好,直到有人说他们希望前两列只读,并且他们希望第三列具有黄色背景,以便用户可以轻松区分哪些列是可编辑的。“没问题”您说,然后您对文本列中缺乏 Background
或 BackgroundColor
属性感到困惑
你,作为一个勤奋的人,不会轻易被这些琐事吓倒,决定转向模板化的单元格以获得对正在发生的事情的更多控制,为只读视图(一个 TextBlock
)和编辑模式(一个 TextBox
)创建一个模板。TextBox
确实有一个 Background
属性,太棒了!但是 TextBlock
没有 Background
属性,惨败。雪上加霜的是,现在排序和验证也无效了。但是,我们在编辑模式下确实有不同的背景颜色,所以这算是一种进步。
利用您精湛的 Google-Fu,您纠正了刚刚创建的两个问题,如下所示
然后,如果 TextBlock
没有 Background
属性,让我们在它后面放一些有背景的东西,比如 Border
,我们应该完成了,对吧?
嗯,这已经很接近了,但是现在,当我们鼠标悬停在行上时,我们看不到那里漂亮的突出显示效果,而且总体上看起来不太好。如果我们可以仍然拥有最初的那些漂亮的 UI 提示,但只是,嗯,使用不同的背景颜色,那就太好了。此时,您可能会开始考虑深入研究视觉状态管理器和动画,但当您看到其他人离开办公室时,您开始怀疑为什么您一整天都在摆弄一列的背景颜色。
忽略这个不相关的信息,你感觉到灵感,并想:“啊!如果背景只部分可见,现有的动画可能会更明显,并且不需要额外的工作!”
这在某种程度上是真的... 只是现在,字体也有点透明,而且无论多少字体加粗或手动设置不透明度似乎都没有帮助
一边诅咒星辰和天堂,一边同时用肘部敲击键盘,你偶然发现了这个,它确实有效!尤里卡,你做到了!
除了... 您感觉有点肮脏,因为为了更改 *&#$^*&^$% 背景颜色,您将一行 XAML 扩展为 15 行,这似乎过分了。此外,列名、使用的背景颜色存在很大的冗余,您将不得不为多列多次复制和粘贴。您简要地考虑使用样式,但这只会对您有所帮助,因为您仍然必须使用此方法为每个列指定两个模板。
你脑海深处的声音告诉你放火烧了这个 DataGrid
并研究供应商网格,但不行,你不会被这些小问题打败。你将找到一种方法来克服这个问题。在用完诅咒词和键盘之前,您得出了最终的解决方案,该解决方案看起来和行为方式完全符合您的期望
public class DataGridTextColumnExtended : DataGridTemplateColumn
{
public string Background { get; set; }
public string BindingProperty
{
set
{
if (value == null)
throw new ArgumentNullException("BindingProperty");
//otherwise sort won't work on template column
base.SortMemberPath = value.ToString();
CellTemplate = (DataTemplate)XamlReader.Load(@"
<DataTemplate
xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>
<Border Background='" + Background + @"' Opacity='.5' />
<TextBlock Text='{Binding Path=" + value + @"}' Margin='4' />
</DataTemplate>
");
CellEditingTemplate = (DataTemplate)XamlReader.Load(@"
<DataTemplate
xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>
<TextBox Background='" + Background + @"' Text='{Binding
NotifyOnValidationError=True, ValidatesOnExceptions=True,
Path=" + value + @", Mode=TwoWay}' />
</DataTemplate>
");
_BindingProperty = value;
}
get
{
return _BindingProperty;
}
}
private string _BindingProperty = null;
}
尽情享用!
关注点
在制作本文的过程中,没有实际的键盘或桌子受到损害。
另外,如果您有更简洁的方法,可以在单独的 XAML 文件中创建自定义列,而不是在 C# 中(同时保持用法 XAML 相同),我很想听听。
历史
- 2010 年 1 月 2 日 - 初始版本。