How can I get a Grid to draw Borders for blank cells?
Asked Answered
E

1

4

I have an ItemsControl which uses a Grid as the ItemsPanelTemplate, and sets the Grid.Column and Grid.Row on the ItemContainerStyle to position data items in the grid

Is there a way to either add GridLines to the Grid, or to fill in the blank cells with a Border?

Right now I have ShowGridLines set to True which makes the dotted lines, however I want Horizontal lines to show up, and I'd prefer solid GridLines

Screenshot

There is a rather large amount of XAML, but here's a screenshot of how my XAML is laid out: XAML Layout

Eidolon answered 16/9, 2011 at 20:7 Comment(3)
What tool did you use for your layout?Triviality
@Triviality Balsamiz, they have a free web demo that I usually useEidolon
Nice ... thanks much!Triviality
C
5

Sorry, styling the grid lines can't be done. Atleast not in an easy way. See the following question for an explanation: How can I change the color of the gridlines of a Grid in WPF?

MSDN docs say "Only dotted lines are available because this property is intended as a design tool to debug layout problems and is not intended for use in production quality code. If you want lines inside a Grid, style the elements within the Grid to have borders."

Edit: If you want the borders you can create a custom Grid and draw the GridLines in OnRender method of the control.

    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;

    namespace BorderGridControl
    {
        public class GridControl : Grid
        {
            #region Properties
            public bool ShowCustomGridLines
            {
                get { return (bool)GetValue(ShowCustomGridLinesProperty); }
                set { SetValue(ShowCustomGridLinesProperty, value); }
            }

            public static readonly DependencyProperty ShowCustomGridLinesProperty =
                DependencyProperty.Register("ShowCustomGridLines", typeof(bool), typeof(GridControl), new UIPropertyMetadata(false));

            
            public Brush GridLineBrush
            {
                get { return (Brush)GetValue(GridLineBrushProperty); }
                set { SetValue(GridLineBrushProperty, value); }
            }

            public static readonly DependencyProperty GridLineBrushProperty =
                DependencyProperty.Register("GridLineBrush", typeof(Brush), typeof(GridControl), new UIPropertyMetadata(Brushes.Black));

            public double GridLineThickness
            {
                get { return (double)GetValue(GridLineThicknessProperty); }
                set { SetValue(GridLineThicknessProperty, value); }
            }

            public static readonly DependencyProperty GridLineThicknessProperty =
                DependencyProperty.Register("GridLineThickness", typeof(double), typeof(GridControl), new UIPropertyMetadata(1.0));
            #endregion

            protected override void OnRender(DrawingContext dc)
            {
                if (ShowCustomGridLines)
                {
                    foreach (var rowDefinition in RowDefinitions)
                    {
                        dc.DrawLine(new Pen(GridLineBrush, GridLineThickness), new Point(0, rowDefinition.Offset), new Point(ActualWidth, rowDefinition.Offset));
                    }

                    foreach (var columnDefinition in ColumnDefinitions)
                    {
                        dc.DrawLine(new Pen(GridLineBrush, GridLineThickness), new Point(columnDefinition.Offset, 0), new Point(columnDefinition.Offset, ActualHeight));
                    }
                    dc.DrawRectangle(Brushes.Transparent, new Pen(GridLineBrush, GridLineThickness), new Rect(0, 0, ActualWidth, ActualHeight));
                }
                base.OnRender(dc);
            }
            static GridControl()
            {
                DefaultStyleKeyProperty.OverrideMetadata(typeof(GridControl), new FrameworkPropertyMetadata(typeof(GridControl)));
            }
        }
    }

I Tried it out and it seems to be working great.

Here an example of using:

    <controls:GridControl ShowCustomGridLines="True"
                          GridLineBrush="Red"
                          GridLineThickness="1">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
    </controls:GridControl>
Chronon answered 16/9, 2011 at 20:13 Comment(6)
Yeah I saw that. I'm beginning to think I need to create something in the Loaded event that fills all blank cells with a Border. Or perhaps overlay two grids on top of eachother and have the top one transparent and the bottom one be filled with borders.Eidolon
Are you creating the RowDefinitions and ColumnDefinitions in Xaml or in code depending on the items?Chronon
In the XAML. Each "Row" is actually its own Grid with 7 Columns.Eidolon
@Rachel: See my updated answer, I believe this is, by far, the easiest way to do this.Chronon
Thanks, that looks quite promising! I'll check it out Monday (home now and have a strict no-work-from-home policy)Eidolon
That worked out great, thanks Meleak! I actually adjusted the ShowCustomGridLines to be of type DataGridGridLinesVisibility instead of bool so I could specify if I want horizontal or vertical lines too :)Eidolon

© 2022 - 2024 — McMap. All rights reserved.