Custom Borders for vlnFlexGrid

ListBox for custom borders
Selection panel for custom borders
This commit is contained in:
Rich 2011-03-18 14:15:51 +00:00
parent 7ac571fdd5
commit 3bb7779e63
5 changed files with 1036 additions and 0 deletions

View File

@ -0,0 +1,36 @@
namespace Volian.Controls.Library
{
partial class BorderListBox
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
}
}

View File

@ -0,0 +1,105 @@
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
namespace Volian.Controls.Library
{
public partial class BorderListBox : ListBox
{
#region Properties
public GridLinePattern SelectedLinePattern
{
get { return (Items[SelectedIndex] as GridLBItem).LinePattern; }
}
#endregion
#region ctor
public BorderListBox()
{
InitializeComponent();
SetupOptions();
}
public BorderListBox(IContainer container)
{
container.Add(this);
InitializeComponent();
SetupOptions();
}
private void SetupOptions()
{
this.DrawMode = DrawMode.OwnerDrawFixed;
//this.Font.Size;
DrawItem += new DrawItemEventHandler(BorderListBox_DrawItem);
//MeasureItem += new MeasureItemEventHandler(BorderListBox_MeasureItem);
Items.Add(new GridLBItem( GridLinePattern.None ));
Items.Add(new GridLBItem(GridLinePattern.Single));
Items.Add(new GridLBItem(GridLinePattern.Double));
Items.Add(new GridLBItem(GridLinePattern.Thick));
Items.Add(new GridLBItem(GridLinePattern.Dashed));
Items.Add(new GridLBItem(GridLinePattern.Dotted));
SelectedIndex = 1;
}
#endregion
#region Event Handlers
void BorderListBox_MeasureItem(object sender, MeasureItemEventArgs e)
{
e.ItemHeight = 22;
}
void BorderListBox_DrawItem(object sender, DrawItemEventArgs e)
{
e.DrawBackground();
e.DrawFocusRectangle();
int y = (e.Bounds.Top + e.Bounds.Bottom) / 2;
GridLBItem myGridLBItem = Items[e.Index] as GridLBItem;
Brush myBrush = new SolidBrush(e.ForeColor);
e.Graphics.DrawString(myGridLBItem.LinePattern.ToString(), Font, myBrush, e.Bounds);
Pen pn = VlnBorders.LinePen(myGridLBItem.LinePattern, e.ForeColor);
int leftMargin = 50;
int rightMargin = 4;
switch (myGridLBItem.LinePattern)
{
case GridLinePattern.Double:
e.Graphics.DrawLine(pn, e.Bounds.Left + leftMargin, y + 1, e.Bounds.Right - rightMargin, y + 1);
e.Graphics.DrawLine(pn, e.Bounds.Left + leftMargin, y - 1, e.Bounds.Right - rightMargin, y - 1);
break;
case GridLinePattern.None:
break;
case GridLinePattern.Single:
case GridLinePattern.Thick:
case GridLinePattern.Dotted:
case GridLinePattern.Dashed:
case GridLinePattern.Mixed:
default:
e.Graphics.DrawLine(pn, e.Bounds.Left + leftMargin, y, e.Bounds.Right - rightMargin, y);
break;
}
}
#endregion
}
public class GridLBItem
{
#region Properties
private GridLinePattern _LinePattern;
public GridLinePattern LinePattern
{
get { return _LinePattern; }
set { _LinePattern = value; }
}
#endregion
#region ctor
public GridLBItem(GridLinePattern linePattern)
{
LinePattern = linePattern;
}
#endregion
#region Public Methods
public override string ToString()
{
return LinePattern.ToString();
}
#endregion
}
}

View File

@ -0,0 +1,36 @@
namespace Volian.Controls.Library
{
partial class BorderSelectionPanel
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
}
}

View File

@ -0,0 +1,410 @@
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace Volian.Controls.Library
{
public delegate void BorderSelectionPanelEvent(object sender, EventArgs args);
public partial class BorderSelectionPanel : Panel
{
#region Events
public event BorderSelectionPanelEvent BordersChanged;
private void OnBordersChanged(object sender, EventArgs args)
{
if (BordersChanged != null) BordersChanged(sender, args);
}
#endregion
#region Properties
private bool _HasRows = true;
public bool HasRows
{
get { return _HasRows; }
set { _HasRows = value; if (!value) _InsideHorizontalBorder = GridLinePattern.None; }
}
private bool _HasColumns = true;
public bool HasColumns
{
get { return _HasColumns; }
set { _HasColumns = value; if (!value) _InsideVerticalBorder = GridLinePattern.None; }
}
private GridLinePattern _SelectedBorder = GridLinePattern.Single;
internal GridLinePattern SelectedBorder
{
get { return _SelectedBorder; }
set { _SelectedBorder = value; }
}
private GridLinePattern _TopBorder = GridLinePattern.Single;
internal GridLinePattern TopBorder
{
get { return _TopBorder; }
set
{
_TopBorder = _TopBorder == value ? GridLinePattern.None : value;
Redraw();
}
}
private GridLinePattern _BottomBorder = GridLinePattern.Single;
internal GridLinePattern BottomBorder
{
get { return _BottomBorder; }
set
{
_BottomBorder = _BottomBorder == value ? GridLinePattern.None : value;
Redraw();
}
}
private GridLinePattern _LeftBorder = GridLinePattern.Single;
internal GridLinePattern LeftBorder
{
get { return _LeftBorder; }
set
{
_LeftBorder = _LeftBorder == value ? GridLinePattern.None : value; ;
Redraw();
}
}
private GridLinePattern _RightBorder = GridLinePattern.Single;
internal GridLinePattern RightBorder
{
get { return _RightBorder; }
set
{
_RightBorder = _RightBorder == value ? GridLinePattern.None : value;
Redraw();
}
}
private GridLinePattern _InsideVerticalBorder = GridLinePattern.Single;
internal GridLinePattern InsideVerticalBorder
{
get { return _InsideVerticalBorder; }
set
{
_InsideVerticalBorder = _InsideVerticalBorder == value ? GridLinePattern.None : value;
Redraw();
}
}
private GridLinePattern _InsideHorizontalBorder = GridLinePattern.Single;
internal GridLinePattern InsideHorizontalBorder
{
get { return _InsideHorizontalBorder; }
set
{
_InsideHorizontalBorder = _InsideHorizontalBorder == value ? GridLinePattern.None : value;
Redraw();
}
}
public GridLinePattern OutlineBorder
{
set { _TopBorder = _BottomBorder = _LeftBorder = _RightBorder = value; Redraw(); }
}
public GridLinePattern InsideBorders
{
set { _InsideHorizontalBorder = _InsideVerticalBorder = value; Redraw(); }
}
public GridLinePattern AllBorders
{
set { _InsideHorizontalBorder = _InsideVerticalBorder = _TopBorder = _BottomBorder = _LeftBorder = _RightBorder = value; Redraw(); }
}
/// <summary>
/// Refresh Borders and raise an event
/// </summary>
private void Redraw()
{
Invalidate();
OnBordersChanged(this, new EventArgs());
}
#endregion
#region Initialize Borders
public void InitializeBorder(GridLinePattern linePattern)
{
_InsideHorizontalBorder = _InsideVerticalBorder = _TopBorder = _BottomBorder = _LeftBorder = _RightBorder = linePattern;
HasRows = true;
HasColumns = true;
Invalidate();
}
public void InitializeBorder(GridLinePattern linePattern, bool hasRows, bool hasColumns)
{
_InsideHorizontalBorder = _InsideVerticalBorder = _TopBorder = _BottomBorder = _LeftBorder = _RightBorder = linePattern;
HasRows = hasRows;
HasColumns = hasColumns;
Invalidate();
}
public void InitializeBorder(GridLinePattern linePattern, int rows, int columns)
{
_InsideHorizontalBorder = _InsideVerticalBorder = _TopBorder = _BottomBorder = _LeftBorder = _RightBorder = linePattern;
HasRows = rows > 0;
HasColumns = columns > 0;
Invalidate();
}
public void InitializeBorder(VlnBorders myBorders, int r1, int c1, int r2, int c2)
{
_TopBorder = myBorders.RangeTopBorder(r1, c1, r2, c2);
_InsideHorizontalBorder = myBorders.RangeHorizontalBorder(r1, c1, r2, c2);
_BottomBorder = myBorders.RangeBottomBorder(r1, c1, r2, c2);
_LeftBorder = myBorders.RangeLeftBorder(r1, c1, r2, c2);
_InsideVerticalBorder = myBorders.RangeVerticalBorder(r1, c1, r2, c2);
_RightBorder = myBorders.RangeRightBorder(r1, c1, r2, c2);
HasRows = r2 > r1;
HasColumns = c2 > c1;
Invalidate();
}
#endregion
#region ctor
public BorderSelectionPanel()
{
InitializeComponent();
this.Paint += new PaintEventHandler(BorderSelectionPanel_Paint);
this.MouseDown += new MouseEventHandler(BorderSelectionPanel_MouseDown);
}
public BorderSelectionPanel(IContainer container)
{
container.Add(this);
InitializeComponent();
this.Paint += new PaintEventHandler(BorderSelectionPanel_Paint);
this.MouseDown += new MouseEventHandler(BorderSelectionPanel_MouseDown);
}
#endregion
#region Event Handlers
private void BorderSelectionPanel_MouseDown(object sender, MouseEventArgs e)
{
if (e.X < 20 && e.Y > 20 && e.Y < Height - 20)
LeftBorder = SelectedBorder;
else if (e.X > Width - 20 && e.Y > 20 && e.Y < Height - 20)
RightBorder = SelectedBorder;
else if (e.Y < 20 && e.X > 20 && e.X < Width - 20)
TopBorder = SelectedBorder;
else if (e.Y > Height - 20 && e.X > 20 && e.X < Width - 20)
BottomBorder = SelectedBorder;
else if (HasRows && ( e.X < (Width / 2) - 2 || e.X > (Width / 2) + 2))
InsideHorizontalBorder = SelectedBorder;
else if (HasColumns && ( e.Y < (Height / 2) - 2 || e.Y > (Height / 2) + 2))
InsideVerticalBorder = SelectedBorder;
else if(HasRows && HasColumns)
InsideVerticalBorder = InsideHorizontalBorder = SelectedBorder;
}
private void BorderSelectionPanel_Paint(object sender, PaintEventArgs e)
{
int margin = 10;
int x1 = margin;
int y1 = margin;
int x2 = Width - margin - 1;
int y2 = Height - margin - 1;
int w2 = Width - 1;
int h2 = Height - 1;
int w1 = Width - 2 * margin - 1;
int h1 = Height - 2 * margin - 1;
int offset = 4;
DrawBackground(e, x1, y1, x2, y2, w1, h1, w2, h2, offset);
DrawBorder(e, x1, y1, x2, y2);
}
private static void DrawBackground(PaintEventArgs e, int x1, int y1, int x2, int y2, int w1, int h1, int w2, int h2, int offset)
{
e.Graphics.FillRectangle(Brushes.White, x1, y1, w1, h1);
e.Graphics.DrawLine(Pens.LightBlue, x1, offset, x1, y1);
e.Graphics.DrawLine(Pens.LightBlue, x2, offset, x2, y1);
e.Graphics.DrawLine(Pens.LightBlue, x1, y2, x1, h2 - offset);
e.Graphics.DrawLine(Pens.LightBlue, x2, y2, x2, h2 - offset);
e.Graphics.DrawLine(Pens.LightBlue, offset, y1, x1, y1);
e.Graphics.DrawLine(Pens.LightBlue, x2, y1, w2 - offset, y1);
e.Graphics.DrawLine(Pens.LightBlue, offset, y2, x1, y2);
e.Graphics.DrawLine(Pens.LightBlue, x2, y2, w2 - offset, y2);
}
private void DrawBorder(PaintEventArgs e, int x1, int y1, int x2, int y2)
{
DrawLineDown(e.Graphics, LeftBorder, x1, y1, x1, y2, TopBorder, BottomBorder);
DrawLineRight(e.Graphics, BottomBorder, x1, y2, x2, y2, LeftBorder, RightBorder);
DrawLineUp(e.Graphics, RightBorder, x2, y2, x2, y1, BottomBorder, TopBorder);
DrawLineLeft(e.Graphics, TopBorder, x2, y1, x1, y1, RightBorder, LeftBorder);
DrawLineVertical(e.Graphics, InsideVerticalBorder, (x1 + x2) / 2, y1, (x1 + x2) / 2, y2, TopBorder, BottomBorder);
DrawLineHorizontal(e.Graphics, InsideHorizontalBorder, x1, (y1 + y2) / 2, x2, (y1 + y2) / 2, LeftBorder, RightBorder);
}
private void DrawLineDown(Graphics graphics, GridLinePattern linePattern, int x1, int y1, int x2, int y2, GridLinePattern startPattern, GridLinePattern endPattern)
{
if (linePattern == GridLinePattern.None) return;
int dyi1 = 0;int dyi2 = 0;int dxi1 = 0;int dxi2 = 0;
int dyo1 = 0;int dyo2 = 0;int dxo1 = 0;int dxo2 = 0;
if (LineWidth(linePattern) == 3)
{
dxo2 = dxo1 = -1;
dyi2 = dyo1 = LineWidth(startPattern) == 3 ? -1 : 0;
dyi1 =dyo2 = LineWidth(endPattern) == 3 ? 1 : 0;
dxi1 = -dxo1; dxi2 = -dxo2; dyi1 = -dyo1; dyi2 = -dyo2;
if (linePattern == GridLinePattern.Thick) dyo2++; // Fix for bug in Graphics. Seems to happen when line is thick.
}
GridSplitLine mySplit = InsideHorizontalBorder == GridLinePattern.Double ? GridSplitLine.Inside : GridSplitLine.None;
DrawTheLine(graphics, linePattern, mySplit, x1, y1, x2, y2, dxi1, dyi1, dxi2, dyi2, dxo1, dyo1, dxo2, dyo2);
}
private void DrawLineRight(Graphics graphics, GridLinePattern linePattern, int x1, int y1, int x2, int y2, GridLinePattern startPattern, GridLinePattern endPattern)
{
if (linePattern == GridLinePattern.None) return;
int dyi1 = 0; int dyi2 = 0; int dxi1 = 0; int dxi2 = 0;
int dyo1 = 0; int dyo2 = 0; int dxo1 = 0; int dxo2 = 0;
if (LineWidth(linePattern) == 3)
{
dyo2 = dyo1 = 1;
dxi2 = dxo1 = LineWidth(startPattern) == 3 ? -1 : 0;
dxi1 = dxo2 = LineWidth(endPattern) == 3 ? 1 : 0;
dxi1 = -dxo1;dxi2 = -dxo2;dyi1 = -dyo1;dyi2 = -dyo2;
if (linePattern == GridLinePattern.Thick) dxo2++; // Fix for bug in Graphics. Seems to happen when line is thick.
}
GridSplitLine mySplit = InsideVerticalBorder == GridLinePattern.Double ? GridSplitLine.Inside : GridSplitLine.None;
DrawTheLine(graphics, linePattern,mySplit, x1, y1, x2, y2, dxi1, dyi1, dxi2, dyi2, dxo1, dyo1, dxo2, dyo2);
}
private void DrawLineUp(Graphics graphics, GridLinePattern linePattern, int x1, int y1, int x2, int y2, GridLinePattern startPattern, GridLinePattern endPattern)
{
if (linePattern == GridLinePattern.None) return;
int dyi1 = 0; int dyi2 = 0; int dxi1 = 0; int dxi2 = 0;
int dyo1 = 0; int dyo2 = 0; int dxo1 = 0; int dxo2 = 0;
if (LineWidth(linePattern) == 3)
{
dxo2 = dxo1 = 1;
dyo1 = LineWidth(startPattern) == 3 ? 1 : 0;
dyo2 = LineWidth(endPattern) == 3 ? -1 : 0;
if (linePattern == GridLinePattern.Thick) dyo1++; // Fix for bug in Graphics. Seems to happen when line is thick.
dxi1 = -dxo1; dxi2 = -dxo2; dyi1 = -dyo1; dyi2 = -dyo2;
}
GridSplitLine mySplit = InsideHorizontalBorder == GridLinePattern.Double ? GridSplitLine.Inside : GridSplitLine.None;
DrawTheLine(graphics, linePattern, mySplit, x1, y1, x2, y2, dxi1, dyi1, dxi2, dyi2, dxo1, dyo1, dxo2, dyo2);
}
private void DrawLineLeft(Graphics graphics, GridLinePattern linePattern, int x1, int y1, int x2, int y2, GridLinePattern startPattern, GridLinePattern endPattern)
{
if (linePattern == GridLinePattern.None) return;
int dyi1 = 0; int dyi2 = 0; int dxi1 = 0; int dxi2 = 0;
int dyo1 = 0; int dyo2 = 0; int dxo1 = 0; int dxo2 = 0;
if (LineWidth(linePattern) == 3)
{
dyo2 = dyo1 = -1;
dxo1 = LineWidth(startPattern) == 3 ? 1 : 0;
dxo2 = LineWidth(endPattern) == 3 ? -1 : 0;
if (linePattern == GridLinePattern.Thick) dxo1++; // Fix for bug in Graphics. Seems to happen when line is thick.
dxi1 = -dxo1; dxi2 = -dxo2; dyi1 = -dyo1; dyi2 = -dyo2;
}
GridSplitLine mySplit = InsideVerticalBorder == GridLinePattern.Double ? GridSplitLine.Inside : GridSplitLine.None;
DrawTheLine(graphics, linePattern, mySplit, x1, y1, x2, y2, dxi1, dyi1, dxi2, dyi2, dxo1, dyo1, dxo2, dyo2);
}
private void DrawLineVertical(Graphics graphics, GridLinePattern linePattern, int x1, int y1, int x2, int y2, GridLinePattern startPattern, GridLinePattern endPattern)
{
if (linePattern == GridLinePattern.None) return;
int dyi1 = 0; int dyi2 = 0; int dxi1 = 0; int dxi2 = 0;
int dyo1 = 0; int dyo2 = 0; int dxo1 = 0; int dxo2 = 0;
if (LineWidth(linePattern) == 3)
{
dxo2 = dxo1 = 1;
dyo1 = LineWidth(startPattern) == 3 ? 1 : 0;
dyo2 = LineWidth(endPattern) == 3 ? -1 : 0;
if (linePattern == GridLinePattern.Thick) dyo1++; // Fix for bug in Graphics. Seems to happen when line is thick.
dxi1 = -dxo1;dyi1 = dyo1;dxi2 = -dxo2;dyi2 = dyo2;
}
else
{
dyo1 = LineWidth(startPattern) == 3 ? 1 : 0;
dyo2 = LineWidth(endPattern) == 3 ? -1 : 0;
}
GridSplitLine mySplit = InsideHorizontalBorder == GridLinePattern.Double ? GridSplitLine.Both : GridSplitLine.None;
DrawTheLine(graphics, linePattern, mySplit, x1, y1, x2, y2, dxi1, dyi1, dxi2, dyi2, dxo1, dyo1, dxo2, dyo2);
}
private void DrawLineHorizontal(Graphics graphics, GridLinePattern linePattern,int x1, int y1, int x2, int y2, GridLinePattern startPattern, GridLinePattern endPattern)
{
if (linePattern == GridLinePattern.None) return;
int dyi1 = 0; int dyi2 = 0; int dxi1 = 0; int dxi2 = 0;
int dyo1 = 0; int dyo2 = 0; int dxo1 = 0; int dxo2 = 0;
if (LineWidth(linePattern) == 3)
{
dyo2 = dyo1 = -1;
dxo1 = LineWidth(startPattern) == 3 ? 1 : 0;
dxo2 = LineWidth(endPattern) == 3 ? -1 : 0;
if (linePattern == GridLinePattern.Thick) dxo1++; // Fix for bug in Graphics. Seems to happen when line is thick.
dxi1 = dxo1;dyi1 = -dyo1;dxi2 = dxo2;dyi2 = -dyo2;
}
else
{
dxo1 = LineWidth(startPattern) == 3 ? 1 : 0;
dxo2 = LineWidth(endPattern) == 3 ? -1 : 0;
}
GridSplitLine mySplit = InsideVerticalBorder == GridLinePattern.Double ? GridSplitLine.Both:GridSplitLine.None;
DrawTheLine(graphics, linePattern,mySplit, x1, y1, x2, y2, dxi1, dyi1, dxi2, dyi2, dxo1, dyo1, dxo2, dyo2);
}
private int LineWidth(GridLinePattern linePattern)
{
return VlnBorders.LineWidth(linePattern);
}
[Flags]
private enum GridSplitLine:int
{
None=0,Inside=1,Outside=2,Both=3
}
private static void DrawTheLine(Graphics graphics, GridLinePattern linePattern, GridSplitLine mySplit, int x1, int y1, int x2, int y2,int dxi1, int dyi1, int dxi2, int dyi2, int dxo1, int dyo1, int dxo2, int dyo2)
{
Pen pn = VlnBorders.LinePen(linePattern,Color.Black);
switch (linePattern)
{
case GridLinePattern.None:
break;
case GridLinePattern.Double:
DrawDoubleLines(graphics, pn, mySplit, x1, y1, x2, y2, dxi1, dyi1, dxi2, dyi2, dxo1, dyo1, dxo2, dyo2);
break;
case GridLinePattern.Thick:
pn.Width = 3;
if (x1 == x2) // Vertical
graphics.DrawLine(pn, x1, y1 + dyo1, x2, y2 + dyo2);
else // Horizontal
graphics.DrawLine(pn, x1 + dxo1, y1, x2 + dxo2, y2);
break;
case GridLinePattern.Single:
case GridLinePattern.Mixed:
case GridLinePattern.Dashed:
case GridLinePattern.Dotted:
default:
graphics.DrawLine(pn, x1 + dxo1, y1 + dyo1, x2 + dxo2, y2 + dyo2);
break;
}
}
private static void DrawDoubleLines(Graphics graphics, Pen pn, GridSplitLine mySplit, int x1, int y1, int x2, int y2, int dxi1, int dyi1, int dxi2, int dyi2, int dxo1, int dyo1, int dxo2, int dyo2)
{
if ((mySplit & GridSplitLine.Inside) > 0)
{
if (x1 == x2)
{
int yh = (y1 + dyi1 + y2 + dyi2) / 2;
int dh = y2 > y1 ? 1 : -1;
graphics.DrawLine(pn, x1 + dxi1, y1 + dyi1, x2 + dxi2, yh - dh); // Inside Line
graphics.DrawLine(pn, x1 + dxi1, yh + dh, x2 + dxi2, y2 + dyi2); // Inside Line
}
else
{
int xh = (x1 + dxi1 + x2 + dxi2) / 2;
int dh = x2 > x1 ? 1 : -1;
graphics.DrawLine(pn, x1 + dxi1, y1 + dyi1, xh - dh, y2 + dyi2); // Inside Line
graphics.DrawLine(pn, xh + dh, y1 + dyi1, x2 + dxi2, y2 + dyi2); // Inside Line
}
}
else
graphics.DrawLine(pn, x1 + dxi1, y1 + dyi1, x2 + dxi2, y2 + dyi2); // Inside Line
if ((mySplit & GridSplitLine.Outside) > 0)
{
if (x1 == x2)
{
int yh = (y1 + dyo1 + y2 + dyo2) / 2;
int dh = y2 > y1 ? 1 : -1;
graphics.DrawLine(pn, x1 + dxo1, y1 + dyo1, x2 + dxo2, yh - dh); // Outside Line
graphics.DrawLine(pn, x1 + dxo1, yh + dh, x2 + dxo2, y2 + dyo2); // Outside Line
}
else
{
int xh = (x1 + dxo1 + x2 + dxo2) / 2;
int dh = x2 > x1 ? 1 : -1;
graphics.DrawLine(pn, x1 + dxo1, y1 + dyo1, xh - dh, y2 + dyo2); // Outside Line
graphics.DrawLine(pn, xh + dh, y1 + dyo1, x2 + dxo2, y2 + dyo2); // Outside Line
}
}
else
graphics.DrawLine(pn, x1 + dxo1, y1 + dyo1, x2 + dxo2, y2 + dyo2); // Outside Line
}
#endregion
}
}

View File

@ -0,0 +1,449 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Schema;
using System.Drawing;
namespace Volian.Controls.Library
{
[Serializable]
[XmlRoot("VlnBorders")]
public class VlnBorders
{
#region Properties
private int _Rows;
[XmlAttribute("Rows")]
public int Rows
{
get { return _Rows; }
set { _Rows = value; }
}
private int _Columns;
[XmlAttribute("Columns")]
public int Columns
{
get { return _Columns; }
set { _Columns = value; }
}
private LinePatternArray _VerticalLines;
public LinePatternArray VerticalLines
{
get { return _VerticalLines; }
set { _VerticalLines = value; }
}
private LinePatternArray _HorizontalLines;
public LinePatternArray HorizontalLines
{
get { return _HorizontalLines; }
set { _HorizontalLines = value; }
}
#endregion
#region ctor
public VlnBorders() { ;}
public VlnBorders(GridLinePattern defaultLinePattern, int rows, int columns)
{
Rows = rows;
Columns = columns;
HorizontalLines = new LinePatternArray(defaultLinePattern, Rows + 1, Columns);
VerticalLines = new LinePatternArray(defaultLinePattern, Rows, Columns + 1);
}
#endregion
#region SetRange - Set the border styles over a range of cells
public void SetRange(int r1, int c1, int r2, int c2,
GridLinePattern top, GridLinePattern middle, GridLinePattern bottom,
GridLinePattern left, GridLinePattern center, GridLinePattern right)
{
for (int c = c1; c <= c2; c++)
{
if (top != GridLinePattern.Mixed) HorizontalLines[r1, c] = top;
for (int r = r1 + 1; r <= r2; r++)
if (middle != GridLinePattern.Mixed) HorizontalLines[r, c] = middle;
if (bottom != GridLinePattern.Mixed) HorizontalLines[r2 + 1, c] = bottom;
}
for (int r = r1; r <= r2; r++)
{
if (left != GridLinePattern.Mixed) VerticalLines[r, c1] = left;
for (int c = c1 + 1; c <= c2; c++)
if (center != GridLinePattern.Mixed) VerticalLines[r, c] = center;
if (right != GridLinePattern.Mixed) VerticalLines[r, c2 + 1] = right;
}
}
#endregion
#region Get Borders over a Range - Return Mixed if multiple values are found.
public GridLinePattern RangeTopBorder(int r1, int c1, int r2, int c2)
{
GridLinePattern linePattern = HorizontalLines[r1, c1];
for (int c = c1; c <= c2; c++)
if (linePattern != HorizontalLines[r1, c]) return GridLinePattern.Mixed;
return linePattern;
}
public GridLinePattern RangeHorizontalBorder(int r1, int c1, int r2, int c2)
{
if (r1 == r2) return GridLinePattern.None;
GridLinePattern linePattern = HorizontalLines[r1 + 1, c1];
for (int r = r1 + 1; r <= r2; r++)
for (int c = c1; c <= c2; c++)
if (linePattern != HorizontalLines[r, c]) return GridLinePattern.Mixed;
return linePattern;
}
public GridLinePattern RangeBottomBorder(int r1, int c1, int r2, int c2)
{
GridLinePattern linePattern = HorizontalLines[r2 + 1, c1];
for (int c = c1; c <= c2; c++)
if (linePattern != HorizontalLines[r2 + 1, c]) return GridLinePattern.Mixed;
return linePattern;
}
public GridLinePattern RangeLeftBorder(int r1, int c1, int r2, int c2)
{
GridLinePattern linePattern = VerticalLines[r1, c1];
for (int r = r1; r <= r2; r++)
if (linePattern != VerticalLines[r, c1]) return GridLinePattern.Mixed;
return linePattern;
}
public GridLinePattern RangeVerticalBorder(int r1, int c1, int r2, int c2)
{
if (c1 == c2) return GridLinePattern.None;
GridLinePattern linePattern = VerticalLines[r1, c1 + 1];
for (int c = c1 + 1; c <= c2; c++)
for (int r = r1 + 1; r <= r2; r++)
if (linePattern != VerticalLines[r, c]) return GridLinePattern.Mixed;
return linePattern;
}
public GridLinePattern RangeRightBorder(int r1, int c1, int r2, int c2)
{
GridLinePattern linePattern = VerticalLines[r1, c2 + 1];
for (int r = r1; r <= r2; r++)
if (linePattern != VerticalLines[r, c2 + 1]) return GridLinePattern.Mixed;
return linePattern;
}
#endregion
#region Insert and Remove Rows and Columns
public void InsertRow(int row)
{
HorizontalLines.InsertRow(row);
VerticalLines.InsertRow(row);
}
public void InsertRows(int row, int count)
{
HorizontalLines.InsertRows(row, count);
VerticalLines.InsertRows(row, count);
}
public void DeleteRow(int row)
{
HorizontalLines.DeleteRow(row);
VerticalLines.DeleteRow(row);
}
public void DeleteRows(int row, int count)
{
HorizontalLines.DeleteRows(row, count);
VerticalLines.DeleteRows(row, count);
}
public void InsertColumn(int column)
{
HorizontalLines.InsertColumn(column);
VerticalLines.InsertColumn(column);
}
public void InsertColumns(int column, int count)
{
HorizontalLines.InsertColumns(column, count);
VerticalLines.InsertColumns(column, count);
}
public void DeleteColumn(int column)
{
HorizontalLines.DeleteColumn(column);
VerticalLines.DeleteColumn(column);
}
public void DeleteColumns(int column, int count)
{
HorizontalLines.DeleteColumns(column, count);
VerticalLines.DeleteColumns(column, count);
}
#endregion
#region Serialize
public override string ToString()
{
return GenericSerializer<VlnBorders>.StringSerialize(this);
}
public static VlnBorders Get(string xml)
{
return GenericSerializer<VlnBorders>.StringDeserialize(xml);
}
#endregion
#region Line Pattern Static Methods
public static int LineWidth(GridLinePattern linePattern)
{
switch (linePattern)
{
case GridLinePattern.Double:
case GridLinePattern.Thick:
return 3;
case GridLinePattern.None:
case GridLinePattern.Single:
case GridLinePattern.Dotted:
case GridLinePattern.Dashed:
case GridLinePattern.Mixed:
default:
return 1;
}
}
public static Pen LinePen(GridLinePattern linePattern, Color foreColor)
{
Pen pn = new Pen(foreColor, 1);
switch (linePattern)
{
case GridLinePattern.None:
pn.Width = 0;
break;
case GridLinePattern.Thick:
pn.Width = 3;
break;
case GridLinePattern.Dotted:
pn.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom;
float[] patternDot = { 1, 2 };
pn.DashPattern = patternDot;
break;
case GridLinePattern.Dashed:
pn.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom;
float[] patternDash = { 6, 6 };
pn.DashPattern = patternDash;
break;
case GridLinePattern.Mixed:
pn.Color = Color.LightGray;
break;
case GridLinePattern.Double:
case GridLinePattern.Single:
default:
break;
}
return pn;
}
#endregion
}
[Serializable]
public class LinePatternArray
{
#region Properties
private int _Rows;
[XmlAttribute("Rows")]
public int Rows
{
get { return _Rows; }
set { _Rows = value; }
}
private int _Columns;
[XmlAttribute("Columns")]
public int Columns
{
get { return _Columns; }
set { _Columns = value; }
}
private GridLinePattern[] _Lines;
public GridLinePattern[] Lines
{
get { return _Lines; }
set { _Lines = value; }
}
#endregion
#region ctor
public LinePatternArray() { ;}
public LinePatternArray(GridLinePattern defaultLinePattern, int rows, int columns)
{
Rows = rows;
Columns = columns;
Lines = new GridLinePattern[rows * columns];
for (int r = 0; r < Rows; r++)
for (int c = 0; c < Columns; c++)
Lines[r * Columns + c] = defaultLinePattern;
}
#endregion
#region Array Access
public GridLinePattern this[int r, int c]
{
get { return Lines[r * Columns + c]; }
set { Lines[r * Columns + c] = value; }
}
#endregion
#region Insert and Delete Rows and Columns
public void InsertRow(int row)
{
InsertRows(row, 1);
}
public void InsertRows(int row, int count)
{
// Create a new Array of the correct size
GridLinePattern[] newLines = new GridLinePattern[(Rows + count) * Columns];
int newRows = Rows + count;
for (int r = 0; r < newRows; r++)
{
int rSrc = r < row ? r : r > row + count ? r - count : row;
for (int c = 0; c < Columns; c++)
{
newLines[r * Columns + c] = Lines[rSrc * Columns + c];
}
}
Lines = newLines;
Rows = newRows;
}
public void DeleteRow(int row)
{
DeleteRows(row, 1);
}
public void DeleteRows(int row, int count)
{
GridLinePattern[] newLines = new GridLinePattern[(Rows - count) * Columns];
int newRows = Rows - count;
for (int r = 0; r < newRows; r++)
{
int rSrc = r < row ? r : r + count;
for (int c = 0; c < Columns; c++)
{
newLines[r * Columns + c] = Lines[rSrc * Columns + c];
}
}
Lines = newLines;
Rows = newRows;
}
public void InsertColumn(int column)
{
InsertColumns(column, 1);
}
public void InsertColumns(int column, int count)
{
// Create a new Array of the correct size
GridLinePattern[] newLines = new GridLinePattern[Rows * (Columns + count)];
int newColumns = Columns + count;
for (int r = 0; r < Rows; r++)
{
for (int c = 0; c < newColumns; c++)
{
int cSrc = c < column ? c : c > column + count ? c - count : column;
newLines[r * newColumns + c] = Lines[r * Columns + cSrc];
}
}
Lines = newLines;
Columns = newColumns;
}
public void DeleteColumn(int column)
{
DeleteColumns(column, 1);
}
public void DeleteColumns(int column, int count)
{
GridLinePattern[] newLines = new GridLinePattern[Rows * (Columns - count)];
int newColumns = Columns - count;
for (int r = 0; r < Rows; r++)
{
for (int c = 0; c < newColumns; c++)
{
int cSrc = c < column ? c : c + count;
newLines[r * newColumns + c] = Lines[r * Columns + cSrc];
}
}
Lines = newLines;
Columns = newColumns;
}
#endregion
}
public static class GenericSerializer<T> where T : class
{
public static string StringSerialize(T t)
{
string strOutput = string.Empty;
XmlSerializer xs = new XmlSerializer(typeof(T));
using (MemoryStream ms = new MemoryStream())
{
xs.Serialize(new NonXsiTextWriter(ms, Encoding.UTF8), t);
//xs.Serialize(ms, t);
ms.Position = 0;
StreamReader sr = new StreamReader(ms);
strOutput = sr.ReadToEnd();
ms.Close();
}
return strOutput;
}
public static T StringDeserialize(string s)
{
T t;
XmlSerializer xs = new XmlSerializer(typeof(T));
UTF8Encoding enc = new UTF8Encoding();
Byte[] arrBytData = enc.GetBytes(s);
using (MemoryStream ms = new MemoryStream(arrBytData))
{
t = (T)xs.Deserialize(ms);
}
return t;
}
//public static void WriteFile(T t, string fileName)
//{
// string strOutput = string.Empty;
// XmlSerializer xs = new XmlSerializer(typeof(T));
// using (FileStream fs = new FileStream(fileName, FileMode.Create))
// {
// xs.Serialize(new NonXsiTextWriter(fs, Encoding.UTF8), t);
// fs.Close();
// }
//}
//public static T ReadFile(string fileName)
//{
// T t;
// XmlSerializer xs = new XmlSerializer(typeof(T));
// using (FileStream fs = new FileStream(fileName, FileMode.Open))
// {
// t = (T)xs.Deserialize(fs);
// }
// return t;
//}
}
public class NonXsiTextWriter : XmlTextWriter
{
public NonXsiTextWriter(TextWriter w) : base(w) { }
public NonXsiTextWriter(Stream w, Encoding encoding)
: base(w, encoding)
{
this.Formatting = Formatting.Indented;
}
public NonXsiTextWriter(string filename, Encoding encoding) : base(filename, encoding) { }
bool _skip = false;
public override void WriteStartAttribute(string prefix, string localName, string ns)
{
if ((prefix == "xmlns" && (localName == "xsd" || localName == "xsi")) || // Omits XSD and XSI declarations.
ns == XmlSchema.InstanceNamespace) // Omits all XSI attributes.
{
_skip = true;
return;
}
if (localName == "xlink_href")
base.WriteStartAttribute(prefix, "xlink:href", ns);
else
base.WriteStartAttribute(prefix, localName, ns);
}
public override void WriteString(string text)
{
if (_skip) return;
base.WriteString(text);
}
public override void WriteEndAttribute()
{
if (_skip)
{ // Reset the flag, so we keep writing.
_skip = false;
return;
}
base.WriteEndAttribute();
}
}
public enum GridLinePattern : int
{
None = 0,
Single = 1,
Double = 2,
Thick = 3,
Dotted = 4,
Dashed = 5,
Mixed = 6
}
}