在Silverlight 5中,如何将每个DataGrid的行背景颜色绑定到其绑定项的属性之一?

时间:2015-03-02 00:51:03

标签: datagrid datatemplate silverlight-5.0 controltemplate datatrigger

  

请注意,这个问题特定于Silverlight 5.有很多类似的问题浮出水面,但通常是关于WPF或以前的Silverlight版本。其他人的目标是Silverlight 5,但是关于DataGrid以外的控件。我一直无法找到一个与此问题完全相同的现有问题;至少没有一个答案适合我。

假设我有这个非常简单的DataGrid(XAML和C#代码向下),它绑定到具有两个属性INotifyPropertyChanged的{​​{1}}类型的集合}和Selected

DataGrid screenshot

我想将每行的背景颜色绑定到其数据项的Text属性(使用一些Selected - 到 - bool转换器)。通常的行状态' (正常,选定,鼠标悬停等)视觉效果和过渡不应受到影响;也就是说,正常的行会被着色,交替的行会稍微亮一点,鼠标覆盖的行会稍微变暗,选择的行会比那些颜色更暗,等等。

其他地方出现的一些明显的解决方案:

我已经搜索了几个小时的解决方案,并且有许多类似的问题浮出水面,但没有一个答案似乎适用于Silverlight 5,或者它们不起作用。似乎有几种方法:

  1. 覆盖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可能不属于此处。

  2. 将所有列更改为TemplateBinding 并使用数据模板:

    Binding

    情况更糟。单元格获得正确的背景颜色,但数据网格的各种视觉状态不再适用。此外,每列必须转换为模板列。第三,当绑定属性更改值时,背景颜色不会更新。

  3. 使用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> 命名空间的类型)。说实话,我还没有弄清楚它应该如何运作。

  4. 问题:

    我真的不想采用必要的代码隐藏,我手动执行此操作。但是,如何在XAML中以正确的方式执行我想要的操作,同时遵循System.Windows.Interactivity视觉状态和行为,并在绑定属性更改时更新行背景?

    有人可以给我一个XAML示例,如何以这种方式将每一行的背景颜色绑定到其绑定项目的属性之一?

    上述数据网格的XAML和C#代码:

    Microsoft.Expression.Interactivity.Core

    DataGridRow

1 个答案:

答案 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>

由于行的背景矩形在控件模板中,并且该背景应随数据而变化,因此在控件模板中放置数据绑定似乎是不可避免的。