WPF 数据网格:奇怪的样式行为
本文关键字:样式 数据 数据网 网格 WPF | 更新日期: 2023-09-27 18:36:04
我在 WPF 中的数据网格控件中有一个奇怪的行为。基本上,我将自定义对象添加到仅包含一列的数据网格中。在本专栏中,我将在堆栈面板中可视化图像和文本块。它工作正常,直到我定义图像的宽度。然后我明白了。
希望有人能帮助我。提前感谢!
下面是用户控件的代码摘录:
<Grid>
<DataGrid Margin="2"
CanUserResizeRows="False"
AutoGenerateColumns="False"
ItemsSource="{Binding dataGridRows}"
SelectionChanged="selectionChanged"
SelectionMode="Single"
Style="{DynamicResource PaletteDataGrid}"
ClipboardCopyMode="None"
CanUserReorderColumns="False"
CanUserResizeColumns="False"
CanUserSortColumns="False"
GridLinesVisibility="None"
HeadersVisibility="None"
HorizontalAlignment="Stretch"
IsReadOnly="True"
BorderBrush="{x:Null}"
RowStyle="{DynamicResource PaletteRowStyle}"
CellStyle="{DynamicResource PaletteDataGridCell}">
<DataGrid.Resources>
<Style TargetType="ScrollBar"
BasedOn="{StaticResource ScrollBar}" />
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding itemImage}"
MaxHeight="20"
MaxWidth="20" />
<TextBlock Text="{Binding itemName}"
VerticalAlignment="Center"
Width="Auto"
Margin="5, 0, 0, 0" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
数据网格的样式模板:
<Style x:Key="PaletteDataGrid"
TargetType="{x:Type DataGrid}">
<Setter Property="Background"
Value="{StaticResource TabBackground}" />
<Setter Property="Foreground"
Value="{StaticResource TabItemActiveText}" />
<Setter Property="BorderBrush"
Value="Transparent" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="RowDetailsVisibilityMode"
Value="VisibleWhenSelected" />
<Setter Property="ScrollViewer.CanContentScroll"
Value="true" />
<Setter Property="ScrollViewer.PanningMode"
Value="VerticalOnly" />
<Setter Property="Stylus.IsFlicksEnabled"
Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGrid}">
<Border BorderBrush="Transparent"
BorderThickness="0,0,0,0"
Background="{StaticResource TabBackground}"
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="0" />
<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 x:Name="PART_ColumnHeadersPresenter"
Grid.Column="1"
Visibility="Hidden" />
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter"
CanContentScroll="{TemplateBinding CanContentScroll}"
Grid.Column="2"
Grid.Row="1" />
<ScrollBar x:Name="PART_VerticalScrollBar"
Grid.Column="0"
Maximum="{TemplateBinding ScrollableHeight}"
Orientation="Vertical"
Grid.Row="1"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"
ViewportSize="{TemplateBinding ViewportHeight}">
</ScrollBar>
</Grid>
</ControlTemplate>
</ScrollViewer.Template>
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping"
Value="true" />
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping"
Value="false" />
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll"
Value="false" />
</MultiTrigger>
</Style.Triggers>
</Style>
<Style x:Key="PaletteRowStyle"
TargetType="{x:Type DataGridRow}">
<Setter Property="Background"
Value="Transparent" />
<Setter Property="SnapsToDevicePixels"
Value="true" />
<Setter Property="Validation.ErrorTemplate"
Value="{x:Null}" />
<Setter Property="ValidationErrorTemplate">
<Setter.Value>
<ControlTemplate>
<TextBlock Foreground="Red"
Margin="2,0,0,0"
Text="!"
VerticalAlignment="Center" />
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridRow}">
<Border x:Name="DGR_Border"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
CornerRadius="2"
SnapsToDevicePixels="True"
Padding="5,5,5,5">
<SelectiveScrollingGrid>
<SelectiveScrollingGrid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</SelectiveScrollingGrid.ColumnDefinitions>
<SelectiveScrollingGrid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</SelectiveScrollingGrid.RowDefinitions>
<DataGridCellsPresenter Grid.Column="1"
ItemsPanel="{TemplateBinding ItemsPanel}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
<DataGridDetailsPresenter Grid.Column="1"
Grid.Row="1"
SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding AreRowDetailsFrozen, ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical}, Converter={x:Static DataGrid.RowDetailsScrollingConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
Visibility="{TemplateBinding DetailsVisibility}" />
<DataGridRowHeader Grid.RowSpan="2"
SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical"
Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.Row}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
</SelectiveScrollingGrid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsNewItem"
Value="True">
<Setter Property="Margin"
Value="{Binding NewItemMargin, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="False">
<Setter Property="Background"
Value="{StaticResource TabBackground}" />
<Setter Property="BorderBrush"
Value="Transparent" />
<Setter Property="BorderThickness"
Value="1,1,1,1" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="Background"
Value="{StaticResource ItemRolloverBackground}" />
<Setter Property="BorderBrush"
Value="{StaticResource TabItemActiveBorder}" />
<Setter Property="BorderThickness"
Value="1,1,1,1" />
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="PaletteDataGridCell"
TargetType="{x:Type DataGridCell}">
<Setter Property="Background"
Value="Transparent" />
<Setter Property="BorderBrush"
Value="Transparent" />
<Setter Property="BorderThickness"
Value="0" />
<Style.Triggers>
<Trigger Property="IsSelected"
Value="True">
<Setter Property="Background"
Value="Transparent" />
<Setter Property="Foreground"
Value="{StaticResource TabItemActiveText}" />
<Setter Property="BorderBrush"
Value="Transparent" />
</Trigger>
<Trigger Property="Selector.IsSelectionActive"
Value="False">
<Setter Property="Background"
Value="Transparent" />
<Setter Property="Foreground"
Value="{StaticResource TabItemActiveText}" />
<Setter Property="BorderBrush"
Value="Transparent" />
</Trigger>
<Trigger Property="IsKeyboardFocusWithin"
Value="True">
</Trigger>
<Trigger Property="IsEnabled"
Value="false">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</Style.Triggers>
</Style>
滚动条样式:
<Style x:Key="ScrollBarLineButton"
TargetType="{x:Type RepeatButton}">
<Setter Property="SnapsToDevicePixels"
Value="True" />
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Setter Property="Focusable"
Value="false" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Border Name="Border"
Margin="1"
CornerRadius="2"
Background="{StaticResource TabItemActiveBorder}"
BorderBrush="{StaticResource TabItemActiveText}"
BorderThickness="1">
<Path HorizontalAlignment="Center"
VerticalAlignment="Center"
Fill="{StaticResource TabItemActiveText}"
Data="{Binding Path=Content,RelativeSource={RelativeSource TemplatedParent}}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed"
Value="true">
<Setter TargetName="Border"
Property="Background"
Value="{StaticResource TabItemActiveBorder}" />
</Trigger>
<Trigger Property="IsEnabled"
Value="false">
<Setter Property="Foreground"
Value="{StaticResource DisabledForegroundBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ScrollBarPageButton"
TargetType="{x:Type RepeatButton}">
<Setter Property="SnapsToDevicePixels"
Value="True" />
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Setter Property="IsTabStop"
Value="false" />
<Setter Property="Focusable"
Value="false" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Border Background="Transparent" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ScrollBarThumb"
TargetType="{x:Type Thumb}">
<Setter Property="SnapsToDevicePixels"
Value="True" />
<Setter Property="Margin"
Value="0,0,10,0" />
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Setter Property="IsTabStop"
Value="false" />
<Setter Property="Focusable"
Value="false" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border CornerRadius="2"
Background="{StaticResource TabItemActiveBorder}"
BorderBrush="{StaticResource TabItemActiveBorder}"
BorderThickness="1" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="VerticalScrollBar"
TargetType="{x:Type ScrollBar}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.00001*" />
</Grid.RowDefinitions>
<Border Grid.RowSpan="1"
CornerRadius="2"
Background="{StaticResource TabBackground}"/>
<Track Name="PART_Track"
Grid.Row="1"
IsDirectionReversed="true">
<Track.DecreaseRepeatButton>
<RepeatButton Style="{StaticResource ScrollBarPageButton}"
Command="ScrollBar.PageUpCommand" />
</Track.DecreaseRepeatButton>
<Track.Thumb>
<Thumb Style="{StaticResource ScrollBarThumb}"
Margin="1,0,1,0"
Background="{StaticResource TabItemInactiveBackground}"
BorderBrush="{StaticResource TabItemInactiveBackground}" />
</Track.Thumb>
<Track.IncreaseRepeatButton>
<RepeatButton Style="{StaticResource ScrollBarPageButton}"
Command="ScrollBar.PageDownCommand" />
</Track.IncreaseRepeatButton>
</Track>
</Grid>
</ControlTemplate>
<Style x:Key="ScrollBar"
TargetType="{x:Type ScrollBar}">
<Setter Property="SnapsToDevicePixels"
Value="True" />
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Style.Triggers>
<Trigger Property="Orientation"
Value="Vertical">
<Setter Property="Width"
Value="8" />
<Setter Property="Height"
Value="Auto" />
<Setter Property="Template"
Value="{StaticResource VerticalScrollBar}" />
</Trigger>
</Style.Triggers>
</Style>
更新
我注意到当我加载溢出当前单元格宽度的项目时,效果会消失。似乎单元格根据内容定义其宽度(这是合乎逻辑的)。但是,如何定义单元格的最大宽度不超过数据网格边界,最小宽度使用整个数据网格宽度?
[这里][2]你可以看到角半径只显示在左侧,而不是在右侧,因为溢出。
更新 2
我想要实现的是这个。
其他信息:数据网格位于绑定到 TabControl 内容的用户控件中。以下是来自mainWindow.xaml的代码:
<Grid Margin="0,96,0,0">
<TabControl ItemContainerStyle="{StaticResource TabItem}"
TabStripPlacement="Right"
ItemsSource="{Binding loadedPalettes}"
Style="{StaticResource TabControl}"
Height="Auto"
SelectionChanged="paletteSelectionChanged"
SelectedIndex="{Binding selPaletteIndex}"
Width="Auto"
Margin="0,5,0,0">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Header}">
<TextBlock.LayoutTransform>
<RotateTransform Angle="270" />
</TextBlock.LayoutTransform>
</TextBlock>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<my:tabDataGrid />
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</Grid>
尝试在 DataTemplate
中使用 Grid
而不是 StackPanel
:
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="{Binding itemImage}" MaxHeight="20"
MaxWidth="20" />
<TextBlock Grid.Column="1" Text="{Binding itemName}"
VerticalAlignment="Center"
Width="Auto"
Margin="5, 0, 0, 0" />
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
好的,我解决了问题。似乎我搞砸了数据网格的行样式模板,忘记给数据网格的DataGridTemplateColumn
一个定义的宽度:
数据网格行样式模板中的滚动查看器:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridRow}">
<Border x:Name="DGR_Border"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
CornerRadius="2"
SnapsToDevicePixels="True"
Padding="5,5,5,5">
<SelectiveScrollingGrid>
<SelectiveScrollingGrid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</SelectiveScrollingGrid.ColumnDefinitions>
<SelectiveScrollingGrid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</SelectiveScrollingGrid.RowDefinitions>
<DataGridCellsPresenter Grid.Column="1"
ItemsPanel="{TemplateBinding ItemsPanel}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
<DataGridDetailsPresenter Grid.Column="1"
Grid.Row="1"
SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding AreRowDetailsFrozen, ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical}, Converter={x:Static DataGrid.RowDetailsScrollingConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
Visibility="{TemplateBinding DetailsVisibility}" />
<DataGridRowHeader Grid.RowSpan="2"
SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical"
Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.Row}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
</SelectiveScrollingGrid>
</Border>
</ControlTemplate>
</Setter.Value>
userControl.xaml 中的数据网格列定义
<DataGrid.Columns>
<DataGridTemplateColumn Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Source="{Binding itemImage}"
Grid.Column="0"
MaxHeight="20"
MaxWidth="20" />
<TextBlock Text="{Binding itemName}"
Grid.Column="1"
Margin="5, 0, 0, 0" />
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
感谢您的回答!