Ответ 1
Относительно короткий ответ
Загрузка ресурсов тем не совпадает с изменением темы на уровне ОС. Загрузка ресурсов тем может привести к неблагоприятным последствиям. С точки зрения WPF в приложении теперь присутствует большое количество неявных стилей. Эти стили могут превзойти другие стили. В нижней строке рассматривается тема, такая как скин приложения, может работать без уточнений.
Есть несколько альтернативных способов моделирования изменения темы.
- Этот ответ на аналогичный вопрос содержит некоторые идеи.
- конечная точка в этой статье базы знаний использует небольшую дозу отражения и должна использоваться до загрузки приложения.
- Этот проект codeplex использует большую дозу отражения и может использоваться в любое время.
Эта проблема демонстрирует довольно сложную функциональность WPF, и часть ее, как представляется, недокументирована. Однако, похоже, это не ошибка. Если это не ошибка, то есть, если все это преднамеренное поведение WPF, вы вполне можете утверждать, что WPF DataGrid плохо разработан в нескольких областях.
Ответ Meleaks был на правильном пути. Однако проблема разрешима, и ее можно решить без ущерба для вашего дизайна или для повторной настройки стиля. И, что еще важнее, проблема отлаживается.
Работает следующий XAML. Я оставил старый XAML прокомментированным, чтобы сделать изменения более заметными. Более подробный анализ проблемы см. В длинном ответе.
DataGridResourceDictionary.xaml:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!--
<Style x:Key="DataGrid_ColumnHeaderStyle" TargetType="DataGridColumnHeader">
-->
<Style TargetType="DataGridColumnHeader" BasedOn="{StaticResource {x:Type DataGridColumnHeader}}">
<!--New-->
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<!---->
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="TextBlock.TextAlignment" Value="Center" />
<Setter Property="TextBlock.TextWrapping" Value="WrapWithOverflow" />
</Style>
<!--
<Style x:Key="DataGrid_CellStyle" TargetType="DataGridCell">
-->
<Style TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}">
<Setter Property="Padding" Value="5,5,5,5" />
<Setter Property="TextBlock.TextAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<!--
<ControlTemplate TargetType="DataGridCell">
<Border Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}">
<ContentPresenter />
</Border>
</ControlTemplate>
-->
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="True">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<!--Additional Feature-->
<!--
Remove keyboard focus cues on cells and tabbing on cells when
only rows are selectable and the DataGrid is readonly.
Note that having some kind of keyboard focus cue is
typically desirable. For example, the lack of any keyboard
focus cues could be confusing if an application has multiple
controls and each control is showing something selected, yet
there is no keyboard focus cue. It not necessarily obvious
what would happen if Control+C or Tab is pressed.
So, when only rows are selectable and the DataGrid is readonly,
is would be ideal to make cells not focusable at all, make
the entire row focusable, and make sure the row has a focus cue.
It would take much more investigation to implement this.
-->
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding RelativeSource={RelativeSource AncestorType=DataGrid}, Path=SelectionUnit}" Value="FullRow"/>
<Condition Binding="{Binding RelativeSource={RelativeSource AncestorType=DataGrid}, Path=IsReadOnly}" Value="True"/>
</MultiDataTrigger.Conditions>
<Setter Property="BorderBrush" Value="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Background}" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="IsTabStop" Value="False" />
</MultiDataTrigger>
</Style.Triggers>
<!---->
</Style>
<!--
<Style TargetType="DataGrid">
-->
<Style TargetType="DataGrid" BasedOn="{StaticResource {x:Type DataGrid}}">
<!--Unworkable Design-->
<!--
<Setter Property="ColumnHeaderStyle" Value="{StaticResource DataGrid_ColumnHeaderStyle}" />
<Setter Property="CellStyle" Value="{StaticResource DataGrid_CellStyle}" />
-->
<Setter Property="Background" Value="White" />
<Setter Property="AlternatingRowBackground" Value="#F0F0F0" />
<!--This was a duplicate of the final PropertySetter.-->
<!--
<Setter Property="VerticalGridLinesBrush" Value="LightGray" />
-->
<Setter Property="HeadersVisibility" Value="Column" />
<Setter Property="SelectionMode" Value="Single" />
<Setter Property="SelectionUnit" Value="FullRow" />
<Setter Property="GridLinesVisibility" Value="Vertical" />
<Setter Property="AutoGenerateColumns" Value="False" />
<Setter Property="CanUserAddRows" Value="False" />
<Setter Property="CanUserDeleteRows" Value="False" />
<Setter Property="CanUserReorderColumns" Value="True" />
<Setter Property="CanUserResizeColumns" Value="True" />
<Setter Property="CanUserResizeRows" Value="False" />
<Setter Property="CanUserSortColumns" Value="True" />
<Setter Property="IsReadOnly" Value="True" />
<Setter Property="BorderBrush" Value="#DDDDDD" />
<Setter Property="HorizontalGridLinesBrush" Value="#DDDDDD" />
<Setter Property="VerticalGridLinesBrush" Value="#DDDDDD" />
</Style>
<Style x:Key="DataGrid_FixedStyle" TargetType="DataGrid" BasedOn="{StaticResource {x:Type DataGrid}}">
<Setter Property="CanUserReorderColumns" Value="False" />
<Setter Property="CanUserResizeColumns" Value="False" />
<Setter Property="CanUserResizeRows" Value="False" />
<Setter Property="CanUserSortColumns" Value="False" />
</Style>
</ResourceDictionary>
App.xaml:
<Application
x:Class="TempProj.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!--
<ResourceDictionary
Source="/PresentationFramework.Aero,
Version=3.0.0.0,
Culture=neutral,
PublicKeyToken=31bf3856ad364e35,
ProcessorArchitecture=MSIL;component/themes/aero.normalcolor.xaml" />
-->
<ResourceDictionary
Source="/PresentationFramework.Aero,
Version=4.0.0.0,
Culture=neutral,
PublicKeyToken=31bf3856ad364e35,
ProcessorArchitecture=MSIL;component/themes/aero.normalcolor.xaml" />
<!--New-->
<!--
This is a modified replica of the DataGridRow Style in the Aero skin that
evaluated next. We are hiding that Style and replacing it with this.
-->
<ResourceDictionary>
<Style x:Key="{x:Type DataGridRow}" TargetType="{x:Type DataGridRow}">
<!--
DataGridRow.Background must not be set in this application. DataGridRow.Background
must only be set in the theme. If it is set in the application,
DataGrid.AlternatingRowBackground will not function properly.
See: https://stackoverflow.com/questions/4239714/why-cant-i-style-a-control-with-the-aero-theme-applied-in-wpf-4-0
The removal of this Setter is the only modification we have made.
-->
<!--
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" />
-->
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="Validation.ErrorTemplate" Value="{x:Null}" />
<Setter Property="ValidationErrorTemplate">
<Setter.Value>
<ControlTemplate>
<TextBlock Margin="2,0,0,0" VerticalAlignment="Center" Foreground="Red" Text="!" />
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridRow}">
<Border x:Name="DGR_Border"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="True">
<SelectiveScrollingGrid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DataGridCellsPresenter Grid.Column="1"
ItemsPanel="{TemplateBinding ItemsPanel}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<DataGridDetailsPresenter SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=AreRowDetailsFrozen, Converter={x:Static DataGrid.RowDetailsScrollingConverter}, ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical}}"
Grid.Column="1" Grid.Row="1"
Visibility="{TemplateBinding DetailsVisibility}" />
<DataGridRowHeader SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical" Grid.RowSpan="2"
Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=HeadersVisibility, Converter={x:Static DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static DataGridHeadersVisibility.Row}}"/>
</SelectiveScrollingGrid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
<!---->
<ResourceDictionary Source="/CommonLibraryWpf;component/ResourceDictionaries/DataGridResourceDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
MainWindow.xaml:
<Window
x:Class="TempProj.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Vector3DCollection x:Key="Coordinates">
<Vector3D X="1" Y="0" Z="0"/>
<Vector3D X="0" Y="22" Z="0"/>
<Vector3D X="0" Y="0" Z="333"/>
<Vector3D X="0" Y="4444" Z="0"/>
<Vector3D X="55555" Y="0" Z="0"/>
</Vector3DCollection>
</Window.Resources>
<Grid>
<DataGrid
Grid.Row="0"
Grid.Column="0"
Style="{StaticResource DataGrid_FixedStyle}"
ItemsSource="{StaticResource Coordinates}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding X}" Header="X" />
<DataGridTextColumn Binding="{Binding Y}" Header="Y" />
<DataGridTextColumn Binding="{Binding Z}" Header="Z" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>