Как я могу заставить сетку рисовать границы для пустых ячеек?

У меня есть ItemsControl, который использует Grid как ItemsPanelTemplate и устанавливает Grid.Column и Grid.Row на ItemContainerStyle для размещения элементов данных в сетке.

Есть ли способ добавить GridLines в сетку или заполнить пустые ячейки границей?

Прямо сейчас у меня ShowGridLines установлено значение True, что делает пунктирные линии, однако я хочу, чтобы отображались горизонтальные линии, и я бы предпочел сплошные линии сетки.

Снимок экрана

Существует довольно большое количество XAML, но вот скриншот того, как устроен мой XAML: XAML Layout


person Rachel    schedule 16.09.2011    source источник
comment
Какой инструмент вы использовали для макета?   -  person AdamBT    schedule 23.03.2016
comment
@AdamBT Balsamiz, у них есть бесплатная веб-демонстрация, которую я обычно использую   -  person Rachel    schedule 23.03.2016
comment
Хорошо ... большое спасибо!   -  person AdamBT    schedule 23.03.2016


Ответы (1)


К сожалению, стилизация линий сетки невозможна. По крайней мере, не простым способом. См. объяснение в следующем вопросе: Как изменить цвет линий сетки сетки в WPF?

В документах MSDN говорится, что доступны только пунктирные линии, поскольку это свойство предназначено в качестве инструмента проектирования для отладки проблем макета и не предназначено для использования в коде качества производства. Если вам нужны линии внутри сетки, стилизуйте элементы внутри сетки так, чтобы они имели границы.

Изменить: если вам нужны границы, вы можете создать собственный Grid и нарисовать метод GridLines в OnRender элемента управления.

    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)));
            }
        }
    }

Я попробовал это, и, кажется, он отлично работает.

Вот пример использования:

    <controls:GridControl ShowCustomGridLines="True"
                          GridLineBrush="Red"
                          GridLineThickness="1">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
    </controls:GridControl>
person Fredrik Hedblad    schedule 16.09.2011
comment
Да, я видел это. Я начинаю думать, что мне нужно создать что-то в событии Loaded, которое заполнит все пустые ячейки границей. Или, возможно, наложить две сетки друг на друга и сделать верхнюю прозрачной, а нижнюю заполнить границами. - person Rachel; 17.09.2011
comment
Вы создаете RowDefinitions и ColumnDefinitions в Xaml или в коде в зависимости от элементов? - person Fredrik Hedblad; 17.09.2011
comment
В XAML. Каждая строка на самом деле является собственной Grid с 7 столбцами. - person Rachel; 17.09.2011
comment
@Rachel: Смотрите мой обновленный ответ, я считаю, что это, безусловно, самый простой способ сделать это. - person Fredrik Hedblad; 17.09.2011
comment
Спасибо, это выглядит многообещающе! Я проверю это в понедельник (сейчас дома и придерживаюсь строгой политики отказа от работы на дому) - person Rachel; 17.09.2011
comment
Отлично получилось, спасибо Мелеак! На самом деле я настроил ShowCustomGridLines так, чтобы он имел тип DataGridGridLinesVisibility вместо bool, чтобы я мог указать, хочу ли я горизонтальные или вертикальные линии :) - person Rachel; 19.09.2011