【问题标题】:Styling a WPF layout grid background (of each cell, row, column)样式化 WPF 布局网格背景(每个单元格、行、列)
【发布时间】:2010-10-08 14:12:27
【问题描述】:

我想知道是否有任何方法可以设置 WPF 布局网格的单元格、行和列的样式。我一直在尝试查找任何信息,但我发现的少数提及并没有提供那么多信息。

我想设置网格的样式,使其看起来像链接的屏幕截图中的那样。

如果实际控件不支持,我能不能以某种方式继承它然后做呢?我对 WPF 很陌生,因此非常感谢任何帮助。

另外一件事,我知道我可以为网格中的每个控件设置样式,但这似乎有点矫枉过正。我想要一个自己做的网格。

screenshot http://img21.imageshack.us/img21/2842/capturehz8.png

【问题讨论】:

    标签: wpf xaml grid styles controltemplates


    【解决方案1】:

    这里有一个快速(非常粗略的示例),您可以随意修改以获得您想要的格式(如果您认真使用 WPF,您会发现 Blend 在使您的布局看起来不错方面有很大帮助):

    <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"                                                                                                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
           <Page.Resources>
               <Style x:Key="CustomerDefinition" TargetType="TextBlock">
                   <Setter Property="Control.FontFamily" Value="Tahoma"/>
                   <Setter Property="Control.FontSize" Value="12"/>
                   <Setter Property="Control.Foreground" Value="Red"/>
               </Style>
               <Style TargetType="{x:Type Label}">
                   <Setter Property="Width" Value="100"/>
               </Style>
               <Style x:Key="{x:Type TextBox}" TargetType="{x:Type TextBox}">
                   <Setter Property="SnapsToDevicePixels" Value="True"/>
                   <Setter Property="OverridesDefaultStyle" Value="True"/>
                   <Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
                   <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
                   <Setter Property="MinWidth" Value="120"/>
                   <Setter Property="MinHeight" Value="20"/>
                   <Setter Property="AllowDrop" Value="true"/>
                   <Setter Property="Width" Value="200"/>
                   <Setter Property="Template">
                       <Setter.Value>
                           <ControlTemplate TargetType="{x:Type TextBoxBase}">
                               <Border
                                   Name="Border"
                                   Background="#FFEBE9E9"
                                   BorderBrush="#FF8B8787"
                                   BorderThickness="1"
                                   CornerRadius="2"
                                   Padding="3">
                                   <ScrollViewer x:Name="PART_ContentHost" Margin="0"/>
                               </Border>
                               <ControlTemplate.Triggers>
                                   <Trigger Property="IsEnabled" Value="False">
                                       <Setter TargetName="Border" Property="Background"
                                                           Value="#EEEEEE"/>
                                       <Setter TargetName="Border" Property="BorderBrush"
                                                           Value="#EEEEEE"/>
                                       <Setter Property="Foreground" Value="#888888"/>
                                   </Trigger>
                               </ControlTemplate.Triggers>
                           </ControlTemplate>
                       </Setter.Value>
                   </Setter>
               </Style>
               <LinearGradientBrush x:Key="NormalBrush" StartPoint="0,0" EndPoint="0,1">
                   <GradientBrush.GradientStops>
                       <GradientStopCollection>
                           <GradientStop Offset="0.0" Color="#FFF0EDED"/>
                           <GradientStop Offset="1.0" Color="#FFE1E0E0"/>
                       </GradientStopCollection>
                   </GradientBrush.GradientStops>
               </LinearGradientBrush>
           </Page.Resources>
           <Grid>
               <Grid.ColumnDefinitions>
                   <ColumnDefinition Width="*"/>
                   <ColumnDefinition Width="*"/>
               </Grid.ColumnDefinitions>
               <Grid.RowDefinitions>
                   <RowDefinition Height="26"/>
                   <RowDefinition Height="23"/>
                   <RowDefinition Height="24"/>
                   <RowDefinition Height="24"/>
                   <RowDefinition Height="24"/>
               </Grid.RowDefinitions>
               <TextBlock
                   Grid.ColumnSpan="2"
                   Grid.Row="0"
                   Style="{StaticResource CustomerDefinition}"
                   Text="Customer Definition"/>
               <Border
                   Grid.Column="0"
                   Grid.Row="1"
                   Background="#FFEBE9E9"
                   BorderBrush="#FF8B8787"
                   BorderThickness="1">
                   <StackPanel Background="{StaticResource NormalBrush}" Orientation="Horizontal">
                       <Label Content="Customer Code"/>
                       <TextBox Text="SMITHA 098 (normally I'd bind here)"/>
                   </StackPanel>
               </Border>
               <Border
                   Grid.Column="1"
                   Grid.Row="1"
                   Background="#FFEBE9E9"
                   BorderBrush="#FF8B8787"
                   BorderThickness="1">
                   <StackPanel Background="{StaticResource NormalBrush}" Orientation="Horizontal">
                       <Label Content="Customer Type"/>
                       <TextBox Text="PRIVATE INDIVIDUAL"/>
                   </StackPanel>
               </Border>
           </Grid> </Page>
    

    【讨论】:

      【解决方案2】:

      我在寻找为 DataGrid 单元格设置边距(或填充)的方法时发现了这篇文章。多亏了(接近尾声)发布的示例 xaml 代码,我的问题得到了解决——非常简约。

      http://forums.silverlight.net/forums/p/16842/55997.aspx

      【讨论】:

        【解决方案3】:

        @Dan 推荐我正在阅读的 WPF Unleashed。就在今天早上,我看到一个部分解决了您的问题。

        第 6 章,第 161 页:

        常见问题解答:如何像使用 HTML 表格的单元格一样为网格单元格提供背景颜色、填充和边框?

        没有内在的机制来赋予网格单元这样的属性,但是您可以很容易地模拟它们,这要归功于多个元素可以出现在任何网格单元中的事实。要为单元格提供背景颜色,您可以简单地使用适当的填充插入一个矩形,默认情况下它会拉伸以填充单元格。要给单元格填充,您可以使用自动调整大小并在适当的子元素上设置边距。对于边框,您可以再次使用 Rectangle,但给它一个适当颜色的显式 Stroke,或者您可以简单地使用 Border 元素。

        请确保在任何其他子项之前将此类矩形或边框添加到网格(或使用 ZIndex 附加属性明确标记它们),以便它们的 Z 顺序将它们放在主要内容的后面。

        顺便说一句,WPF 释放的岩石。写得很好,全彩印刷更容易阅读。

        【讨论】:

        • 这是 WPF 4 Unleashed 2010 版的第 5 章第 128 页。
        【解决方案4】:

        我建议您在样式中使用边框。

        您可以通过为每行和每列创建边框并相应地设置行跨度和列跨度来轻松地重新创建该布局。

        colspan 2 将有 5 个边框,这些边框将处理每行的渐变背景以及每行顶部和底部的边框。然后,您将拥有 2 个行跨度为 5 的边框,这些边框将处理列边框。想象一下,您正在覆盖边框以形成您所追求的视觉网格效果。

        对于表头和外边框,只需根据需要用边框和样式包裹整个网格即可。

        我建议将您的样式存储为资源,这样您就可以将所有样式信息保存在一个地方。

        注意了解样式的工作原理,因为它非常强大,但是有一个学习曲线,因为它与 CSS 的工作方式完全不同。如果可以的话,我会推荐阅读WPF Unleashed

        【讨论】:

        • 谢谢丹,但如果这是唯一的方法,我可以不以某种方式继承网格并自动添加边框吗?我不想必须将每个控件添加到边框。
        • 嗨 Mladen,您不必让每个控件都成为边框的子控件。您的控件将是网格的子级。您只是为了网格“外观”而将边框添加为网格的额外子项。想象你将边框覆盖在其他所有东西的顶部(或后面)。
        【解决方案5】:

        WPF Grid 没有可见的单元格。可以将它们视为不可见的网格线,您可以根据这些网格线对齐子元素。

        因此,要设置网格单元格的样式,您必须设置网格内对齐的项目的样式。

        Grid 视为类似于WinForms DataGrid 的东西令人困惑。我猜它最接近的 WinForms 等效项是 TableLayout 控件。

        查看一些第 3 方网格控件。我在测试版时使用了 DevExpress,发现它非常简单。

        【讨论】:

        • 我试图模仿的实际组件是 DevExpress 布局控件(winforms)。我只是真的想为单元格添加背景和边距,但它似乎超出了 WPF 布局网格。
        • 我明白你想要什么。我只是说 WPF Grid 控件不是用于显示表格数据,而是用于布局。也许 MS 应该叫它 GridLayout 更清楚。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-23
        • 2011-11-17
        • 1970-01-01
        • 2018-04-17
        • 1970-01-01
        相关资源
        最近更新 更多