2013-02-27 78 views
0

我有一个WPF应用程序,它使用DataGrid控件并由警察在警车中使用。我使用合并字典来实现日夜模式,其中当您在两者之间切换程序时,调色板会发生变化。应用程序收集我公司制造的特殊传感器的数据并显示给高级职员。DataGridRow的背景属性是错误的

问题DataGrid行为奇怪。程序第一次启动时,它最初是空的。随着数据的收集,行被添加到DataGrid。当您启动程序时,它最初处于日间模式。问题是第一行的背景不会更改为控件的夜间模式颜色。它保持白色,这是白天模式的颜色。如果您在日间模式和夜间模式之间来回切换,则会保持白色。

这与添加到DataGrid之后的任何行不同,后者具有正确的颜色并在颜色之间来回切换。

下面是我在我的App.xaml定义的DataGridRow类风格:

<Application x:Class="MyApplication.App" 
    . . .> 

    <Application.Resources> 
     <ResourceDictionary> 
      <ResourceDictionary.MergedDictionaries> 
       <ResourceDictionary Source="pack://application:,,,/MyApplication;component/DayTime.xaml" /> 

       <ResourceDictionary> 
        . . . 
        <Style TargetType="{x:Type DataGridRow}"> 
        <Setter Property="BorderBrush"  Value="{DynamicResource DataBorder}" /> 
        <Setter Property="Background"  Value="{DynamicResource DataBackground}" /> 
        <Setter Property="Foreground"  Value="{DynamicResource DataForeground}" /> 
       <Style.Triggers> 
        <Trigger Property="IsFocused" Value="True"> 
         <Setter Property="Background" Value="{DynamicResource DataBackground}" /> 
         <Setter Property="BorderBrush" Value="{DynamicResource DataBorderFocused}" /> 
         <Setter Property="Foreground" Value="{DynamicResource DataForeground}" /> 
        </Trigger> 
        <Trigger Property="IsKeyboardFocused" Value="True"> 
         <Setter Property="Background" Value="{DynamicResource DataBackground}" /> 
         <Setter Property="BorderBrush" Value="{DynamicResource DataBorderFocused}" /> 
         <Setter Property="Foreground" Value="{DynamicResource DataForeground}" /> 
        </Trigger> 
        <Trigger Property="IsSelected" Value="True"> 
         <Setter Property="Background" Value="{DynamicResource DataBackgroundSelected}" /> 
         <Setter Property="BorderBrush" Value="{DynamicResource DataBorderSelected}" /> 
         <Setter Property="Foreground" Value="{DynamicResource DataForegroundSelected}" /> 
        </Trigger> 
       </Style.Triggers> 
      </Style> 
      . . . 
       </ResourceDictionary> 
      </ResourceDictionary> 
     </ResourceDictionary> 
    </Application.Resources> 
</Application> 

当我在程序运行snoop并深入到有问题的DataGridRow,该Background属性的值是白(#FFFFFFFF),并将其值设置为“DefaultStyle”。但这似乎不是我定义的样式,因为当我切换到白天模式&时,它不会改变。我认为这是微软定义的默认样式,它根本不使用我的样式。但是只有在插入DataGrid的第一行中,如果它最初是空的。

对于后续行,“值来源”列显示“ParentTemplate”。这一定是我的风格,因为当您切换夜间模式时,背景颜色会发生适当变化。

如何解决这个问题,使DataGrid中的每一行都正确?

编辑:

在完整性的利益,这里是由DataGrid控制使用的样式,在情况下,它可以帮助。

<Style TargetType="{x:Type DataGrid}"> 
    <Setter Property="Background"     Value="{DynamicResource DataBackground}" /> 
    <Setter Property="Foreground"     Value="{DynamicResource TextForeground}" /> 
    <Setter Property="BorderBrush"     Value="{DynamicResource DataBorder}" /> 
    <Setter Property="BorderThickness"    Value="1" /> 
    <Setter Property="RowDetailsVisibilityMode"  Value="VisibleWhenSelected" /> 
    <Setter Property="ScrollViewer.CanContentScroll" Value="true" /> 
    <Setter Property="ScrollViewer.PanningMode"  Value="Both" /> 
    <Setter Property="Stylus.IsFlicksEnabled"  Value="False" /> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type DataGrid}"> 
       <Border BorderBrush="{TemplateBinding BorderBrush}" 
         BorderThickness="{TemplateBinding BorderThickness}" 
         Background="{TemplateBinding Background}" 
         Padding="{TemplateBinding Padding}" 
         SnapsToDevicePixels="True"> 
        <ScrollViewer x:Name="DG_ScrollViewer" Focusable="false"> 
         <ScrollViewer.Template> 
          <ControlTemplate TargetType="{x:Type ScrollViewer}"> 
           <Grid> 
            <Grid.ColumnDefinitions> 
             <ColumnDefinition Width="Auto" /> 
             <ColumnDefinition Width="*" /> 
             <ColumnDefinition Width="Auto" /> 
            </Grid.ColumnDefinitions> 
            <Grid.RowDefinitions> 
             <RowDefinition Height="Auto" /> 
             <RowDefinition Height="*" /> 
             <RowDefinition Height="Auto" /> 
            </Grid.RowDefinitions> 
            <Button Command="{x:Static DataGrid.SelectAllCommand}" 
              Focusable="false" 
              Style="{DynamicResource {ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle, TypeInTargetAssembly={x:Type DataGrid}}}" 
              Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.All}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" 
              Width="{Binding CellsPanelHorizontalOffset, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" /> 
            <DataGridColumnHeadersPresenter Grid.Column="1" 
                    x:Name="PART_ColumnHeadersPresenter" 
                    Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.Column}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" /> 
            <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" 
                  CanContentScroll="{TemplateBinding CanContentScroll}" 
                  Grid.ColumnSpan="2" 
                  Grid.Row="1" /> 
            <ScrollBar x:Name="PART_VerticalScrollBar" 
               Grid.Column="2" 
               Maximum="{TemplateBinding ScrollableHeight}" 
               Orientation="Vertical" 
               Grid.Row="1" 
               Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" 
               Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" 
               ViewportSize="{TemplateBinding ViewportHeight}" 
               MinWidth="45" Width="50" /> 
            <Grid Grid.Column="1" 
              Grid.Row="2"> 
             <Grid.ColumnDefinitions> 
              <ColumnDefinition Width="{Binding NonFrozenColumnsViewportHorizontalOffset, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" /> 
              <ColumnDefinition Width="*" /> 
             </Grid.ColumnDefinitions> 
             <ScrollBar x:Name="PART_HorizontalScrollBar" 
                Grid.Column="1" 
                Maximum="{TemplateBinding ScrollableWidth}" 
                Orientation="Horizontal" 
                Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" 
                Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" 
                ViewportSize="{TemplateBinding ViewportWidth}" /> 
            </Grid> 
           </Grid> 
          </ControlTemplate> 
         </ScrollViewer.Template> 
         <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> 
        </ScrollViewer> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
    <Style.Triggers> 
     <Trigger Property="IsGrouping" Value="true"> 
      <Setter Property="ScrollViewer.CanContentScroll" Value="false" /> 
     </Trigger> 
    </Style.Triggers> 
</Style> 

编辑:

作为expermient,我加入该成员变量与问题的窗口的代码隐藏:

private static Style dataGridRowStyle = null; 

然后,我添加此代码的构造我的窗口:

if (dataGridRowStyle == null) { 
    dataGridRowStyle = FindResource(typeof(DataGridRow)) as Style; 
    MyGrid.RowStyle = dataGridRowStyle; 
} 

通过这样做,我看到每行添加到DataGrid公顷d原始的默认样式。当我将上面的代码移动到Loaded事件处理程序时,这也发生了。

接下来,我删除了上面的代码,并将一个x:Key属性添加到了app.xaml文件中的Style定义中。然后我加入这个属性到DataGrid控制的定义:

RowStyle={DynamicResource MyDataGridRowStyle} 

现在每行有我的风格。这很好,但我认为只用TargetType属性声明我的样式足以让它适用于所有行。为什么不呢?

回答

1

经过多次头部搔抓,心痛和网络搜索之后,我终于弄清楚了我的程序中发生了什么。

我的程序使用合并字典来实现白天和黑夜模式。事实证明,合并的字典是问题的原因,正如解释in this tutorial

修复是将默认样式放入根词典中。实际上,我的代码在标签内的资源字典中包含了所有模板。我将它们提升了一个级别,现在WPF在第一行和每一行都找到了我的默认模板。