请注意,这个问题特定于Silverlight 5.有很多类似的问题浮出水面,但通常是关于WPF或以前的Silverlight版本。其他人的目标是Silverlight 5,但是关于
DataGrid
以外的控件。我一直无法找到一个与此问题完全相同的现有问题;至少没有一个答案适合我。
假设我有这个非常简单的DataGrid
(XAML和C#代码向下),它绑定到具有两个属性INotifyPropertyChanged
的{{1}}类型的集合}和Selected
:
我想将每行的背景颜色绑定到其数据项的Text
属性(使用一些Selected
- 到 - bool
转换器)。通常的行状态' (正常,选定,鼠标悬停等)视觉效果和过渡不应受到影响;也就是说,正常的行会被着色,交替的行会稍微亮一点,鼠标覆盖的行会稍微变暗,选择的行会比那些颜色更暗,等等。
我已经搜索了几个小时的解决方案,并且有许多类似的问题浮出水面,但没有一个答案似乎适用于Silverlight 5,或者它们不起作用。似乎有几种方法:
覆盖Brush
控制模板并绑定其DataGridRow
的{{1}}媒体资源:
BackgroundRectangle
这最初起作用,并且正确呈现了视觉状态(因为Background
视觉状态仅影响<sdk:DataGrid …>
<sdk:DataGrid.RowStyle>
<Style TargetType="sdk:DataGridRow">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
…
<Rectangle x:Name="BackgroundRectangle" …
Background="{Binding Selected, Converter={StaticResource boolToBrush}}" />
…
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</sdk:DataGrid.RowStyle>
…
</sdk:DataGrid>
的不透明度;有关详细信息,请参阅the default control template definition。
问题在于,当绑定项目时,行背景颜色不会发生变化。 DataGrid
属性会更改值。好像BackgroundRectangle
有一个Selected
。
另外,我已经读过应该避免控件模板中的数据绑定。 {Binding}
在控制模板中很好用,但常规Mode=OneTime
可能不属于此处。
将所有列更改为TemplateBinding
并使用数据模板:
Binding
情况更糟。单元格获得正确的背景颜色,但数据网格的各种视觉状态不再适用。此外,每列必须转换为模板列。第三,当绑定属性更改值时,背景颜色不会更新。
使用Expression Blend数据触发器(来自<sdk:DataGridTemplateColumn>
和<sdk:DataGrid …>
<sdk:DataGrid.Columns>
<sdk:DataGridTemplateColumn Header="Selected">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid Background="{Binding Selected, Converter={StaticResource boolToBrush}}">
<CheckBox IsChecked="{Binding Selected}" />
</Grid>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
… <!-- repeat the above for each column -->
</sdk:DataGridTemplateColumn>
</sdk:DataGrid.Columns>
…
</sdk:DataGrid>
命名空间的类型)。说实话,我还没有弄清楚它应该如何运作。
我真的不想采用必要的代码隐藏,我手动执行此操作。但是,如何在XAML中以正确的方式执行我想要的操作,同时遵循System.Windows.Interactivity
视觉状态和行为,并在绑定属性更改时更新行背景?
有人可以给我一个XAML示例,如何以这种方式将每一行的背景颜色绑定到其绑定项目的属性之一?
Microsoft.Expression.Interactivity.Core
DataGridRow
答案 0 :(得分:0)
似乎有效的一件事是重写控件模板并将Expression Blend数据触发器放在BackgroundRectangle
中。
从DataGridRow
的默认控件模板开始(您可以找到on the MSDN page 'DataGrid Styles and Templates')。唯一需要改变的是<Rectangle x:Name="BackgroundRectangle">
:
<!--
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:ei="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expressions.Interactions"
-->
<sdk:DataGrid …>
<sdk:DataGrid.RowStyle>
<Style TargetType="sdk:DataGridRow">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
… <!-- use DataGridRow standard control template, except for this: -->
<Rectangle x:Name="BackgroundRectangle" …
Background="{Binding Selected, Converter={StaticResource boolToBrush}}">
<i:Interaction.DataTriggers>
<ei:PropertyChangedTrigger Binding="{Binding Selected}" Value="True">
<ei:PropertyChangedTrigger.Actions>
<ei:ChangePropertyAction TargetName="BackgroundRectangle"
PropertyName="Fill"
Value="{Binding Selected, Converter={StaticResource boolToBrush}}" />
</ei:PropertyChangedTrigger.Actions>
</ei:PropertyChangedTrigger>
</i:Interaction.DataTriggers>
<Rectangle>
…
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</sdk:DataGrid.RowStyle>
…
</sdk:DataGrid>
由于行的背景矩形在控件模板中,并且该背景应随数据而变化,因此在控件模板中放置数据绑定似乎是不可避免的。