2013-02-27 74 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在第一行和每一行都找到了我的默認模板。