ایجاد Grid Control در WPF

سه شنبه 28 مهر 1394

در این پست خواهیم آموخت که چگونه یک کنترل grid سفارشی ایجاد کنیم که خطوط solid داشته باشد. همچنین امکان انتخاب رنگ، ضخامت و دیدن خطوط جدول را داشته باشیم.

ایجاد Grid Control در WPF

در اسناد MSDN گفته می شود که تنها خطوط نقطه چین در دسترس می باشند زیرا این ویژگی بعنوان یک ابزار طراحی برای اشکال زدایی مسائل طرح بندی در نظر گرفته شده است. و برای تولید کد با کیفیت درنظر گرفته نشده است.

اگر می خواهید داخل یک grid خطوط وجود داشته باشد، استایل المان ها درون grid حاشیه خواهند داشت. حتی سورس کد Grid در چیزی شبیه این را توضیح می دهد.

اکنون برنامه ای را ایجاد می کنیم که نیازهای بالا را انجام دهد.

enum برای دیدن خطوط grid می باشد که می تواند هر دو طرف، افقی، عمودی یا بدون خطوط باشد.

public enum GridLinesVisibilityEnum
       {
           Both,
           Vertical,
           Horizontal,
           None
       }

 

ما یک DependancyProperty داریم که  ShowCustomGridLines را فراخوانی کرده که نمایش خطوط Solid را انجام می دهد.

public bool ShowCustomGridLines
    {
        get { return (bool)GetValue(ShowCustomGridLinesProperty); }
        set { SetValue(ShowCustomGridLinesProperty, value); }
    }

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

DependencyProperty از نوع GridLineVisibilityEnum که GridLinesVisibility نامیده شده و  برای نمایش GridLines می باشد.

public bool ShowCustomGridLines
    {
        get { return (bool)GetValue(ShowCustomGridLinesProperty); }
        set { SetValue(ShowCustomGridLinesProperty, value); }
    }

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

DependencyProperty از نوع Brush که GridlineBrush نام دارد و رنگ خطوط حاشیه را مشخص می کند.

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

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

 

DependencyProperty از نوع double بنام GridLinesThickness که ضخامت حاشیه GridLines را تعیین می کند.

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

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

در انتها متد ()OnRender برای کشیدن GridLines می باشد.

if (ShowCustomGridLines)
         {
             if (GridLinesVisibility == GridLinesVisibilityEnum.Both)
             {
                 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));
             }
             else if (GridLinesVisibility == GridLinesVisibilityEnum.Vertical)
             {
                 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));
             }
             else if (GridLinesVisibility == GridLinesVisibilityEnum.Horizontal)
             {
                 foreach (var rowDefinition in RowDefinitions)
                 {
                     dc.DrawLine(new Pen(GridLineBrush, GridLineThickness),
         new Point(0, rowDefinition.Offset),
         new Point(ActualWidth, rowDefinition.Offset));
                 }
                 dc.DrawRectangle(Brushes.Transparent,
         new Pen(GridLineBrush, GridLineThickness),
         new Rect(0, 0, ActualWidth, ActualHeight));
             }
             else if (GridLinesVisibility == GridLinesVisibilityEnum.Horizontal)
             {

             }

         }
         base.OnRender(dc);

پس در نهایت مجموعه کامل کلاس سفارشی شبیه زیر خواهد بود:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace GridWithSolidGridLines
{
    public class CustomGrid : Grid
    {
        #region GridLinesVisibilityEnum
        public enum GridLinesVisibilityEnum
        {
            Both,
            Vertical,
            Horizontal,
            None
        }
        #endregion


        #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(CustomGrid), new UIPropertyMetadata(false));

        public GridLinesVisibilityEnum GridLinesVisibility
        {
            get { return (GridLinesVisibilityEnum)GetValue(GridLinesVisibilityProperty); }
            set { SetValue(GridLinesVisibilityProperty, value); }
        }

        public static readonly DependencyProperty GridLinesVisibilityProperty =
            DependencyProperty.Register("GridLinesVisibility", 
		typeof(GridLinesVisibilityEnum), typeof(CustomGrid), 
		new UIPropertyMetadata(GridLinesVisibilityEnum.Both));

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

        public static readonly DependencyProperty GridLineBrushProperty =
            DependencyProperty.Register("GridLineBrush", typeof(Brush), 
		typeof(CustomGrid), 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(CustomGrid), new UIPropertyMetadata(1.0));
        #endregion

        protected override void OnRender(DrawingContext dc)
        {
            if (ShowCustomGridLines)
            {
                if (GridLinesVisibility == GridLinesVisibilityEnum.Both)
                {
                    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));
                }
                else if (GridLinesVisibility == GridLinesVisibilityEnum.Vertical)
                {
                    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));
                }
                else if (GridLinesVisibility == GridLinesVisibilityEnum.Horizontal)
                {
                    foreach (var rowDefinition in RowDefinitions)
                    {
                        dc.DrawLine(new Pen(GridLineBrush, GridLineThickness), 
			new Point(0, rowDefinition.Offset), 
			new Point(ActualWidth, rowDefinition.Offset));
                    }
                    dc.DrawRectangle(Brushes.Transparent, 
			new Pen(GridLineBrush, GridLineThickness), 
			new Rect(0, 0, ActualWidth, ActualHeight));
                }
                else if (GridLinesVisibility == GridLinesVisibilityEnum.Horizontal)
                {

                }
            }
            base.OnRender(dc);
        }
        static CustomGrid()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomGrid), 
			new FrameworkPropertyMetadata(typeof(CustomGrid)));
        }
    }
}

در انتها ما می توانیم از این کنترل سفارشی برای XAML و ایجاد کنترل grid با خطوط solid و رنگ و ضخامت می باشد.

<Window x:Class="GridWithSolidGridLines.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:customGrid="clr-namespace:GridWithSolidGridLines"
        Title="MainWindow" Height="350" Width="525">
    <customGrid:CustomGrid ShowCustomGridLines="True" 
    GridLineBrush="DodgerBlue" GridLineThickness="2">
        <customGrid:CustomGrid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </customGrid:CustomGrid.RowDefinitions>
        <customGrid:CustomGrid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </customGrid:CustomGrid.ColumnDefinitions>
    </customGrid:CustomGrid>
</Window>

کد XAML بالا چیزی مانند زیر را ایجاد خواهد کرد. در تصویر زیر جدول دارای خطوط افقی و عمودی  solid آبی می باشد. GridLinesVisibility  بصورت پیشفرض برای هردو طرف می باشد.

اگر ما بخواهیم تنها خطوط افقی داشته باشیم، می توانیم خصوصیت GridLinesVisibility را برای Horizontal تنظیم کنیم و نتیجه ای مانند تصویر زیر را خواهد داشت.

 

بطور مشابه خصوصیت GridLinesVisibility را برای حالت Vertical تنظیم کرده و نتیجه را مانند تصویر زیر ببینیم.

 

 

 

فایل های ضمیمه

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان
  • WPF
  • 2k بازدید
  • 2 تشکر

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید