I am a beginner programmer,I split an image into 16 parts (I'm making a picture puzzle game) And each one is inside a picturebox And randomly places them have
changed Now I want to know the beginning and end of each image I cut it connects to another image (I mean, any image Continue other). Is such a thing possible? Do you have a better idea?
namespace ImagePuzzelGame
{
public partial class Form1 : Form
{
Point move;
bool isDragging = false;
public Dictionary<int, Point> pics
{
set;
get;
}
private Point _defaultlocation = new Point(306, 306);
Random rnd = new Random();
public Point DefaultLocation
{
get
{
return _defaultlocation;
}
set
{
_defaultlocation = value;
}
}
public List<PictureBox> picPuzzle
{
get;
set;
}
public Bitmap newImage
{
get; set;
}
public Form1()
{
InitializeComponent();
pics = new Dictionary<int, Point>()
{
{1,new Point(0,0) },
{2,new Point(100,0) },
{3,new Point(200,0) },
{4,new Point(300,0) },
{5,new Point(400,0) },
{6,new Point(0,119) },
{7,new Point(100,119) },
{8,new Point(200,119) },
{9,new Point(300,119) },
{10,new Point(400,119) },
{11,new Point(0,325) },
{12,new Point(100,325) },
{13,new Point(200,325) },
{14,new Point(300,325) },
{15,new Point(400,325) },
};
List<PictureBox> picturebox = new List<PictureBox>
{
pictureBox1,pictureBox2,pictureBox3,pictureBox4,pictureBox5,pictureBox6,pictureBox7,
pictureBox8,pictureBox9,pictureBox10,pictureBox11,pictureBox12,pictureBox13,pictureBox14,pictureBox15,pictureBox16
};
picPuzzle = picturebox;
resizeImage();
cropImage();
shufflePuzzle();
}
public void shufflePuzzle()
{
int numberSelect;
int index = 0;
Point virtualLocation;
List<int> selected = new List<int>();
while (selected.Count < picPuzzle.Count)
{
int randomSelectPuzzle = rnd.Next(0, 16);
if (selected.Contains(randomSelectPuzzle))
{
randomSelectPuzzle = rnd.Next(0, 16);
}
else
{
numberSelect = randomSelectPuzzle;
virtualLocation = new Point(picPuzzle[numberSelect].Location.X, picPuzzle[numberSelect].Location.Y);
picPuzzle[numberSelect].Location = new Point(DefaultLocation.X, DefaultLocation.Y);
DefaultLocation = virtualLocation;
selected.Add(randomSelectPuzzle);
}
}
}
public void resizeImage()
{
Bitmap newImage = new Bitmap(320, 320);
Bitmap srcImage = new Bitmap(#"C:\Users\bbmm\Desktop\images\lukas-graham.jpg");
using (Graphics gr = Graphics.FromImage(newImage))
{
gr.SmoothingMode = SmoothingMode.HighQuality;
gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
gr.DrawImage(srcImage, new Rectangle(0, 0, 320, 320));
}
this.newImage = newImage;
try
{
Bitmap bt = new Bitmap(newImage);
bt.Save(#"E:\img\pic.jpg");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public void cropImage()
{
var filename = #"E:\img\pic.jpg";
Rectangle cropRect;
Bitmap[] src = new Bitmap[16];
Bitmap[] target = new Bitmap[16];
int x = 0, y = 0;
int index = 0;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (index == 17)
{
return;
}
cropRect = new Rectangle(new Point(x, y), new Size(new Point(100, 100)));
src[index] = Image.FromFile(filename) as Bitmap;
target[index] = new Bitmap(cropRect.Width, cropRect.Height);
using (Graphics g = Graphics.FromImage(target[index]))
{
g.DrawImage(src[index], new Rectangle(0, 0, target[index].Width, target[index].Height), cropRect, GraphicsUnit.Pixel);
}
picPuzzle[index].Image = target[index];
x += 100;
index++;
}
y += 100;
x = 0;
}
}
public Point HoldLocation
{
get;
set;
}
private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
isDragging = true;
move = e.Location;
}
public List<PictureBox> pastePics { get; set; }
private void pictureBox_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging)
{
PictureBox pb = (PictureBox)sender;
pb.Left += e.X - move.X;
pb.Top += e.Y - move.Y;
pb.BringToFront();
}
}
private void pictureBox_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
}
}
}
Related
I am trying to add a close button on the tab pages of TabControl and
change the color of the close button from light gray to black when
mouse hovers over it. However, the color never changes.
The DrawEventArgsCustom class is created to indicate that the mouse is
hovering over the close button. When it's true, the statement to
change the color is executed but color never changes.
private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
{
try
{
Rectangle r = e.Bounds;
r = this.tabControl1.GetTabRect(e.Index);
r.Offset(2, 2);
Brush TitleBrush = new SolidBrush(Color.Black);
Brush CloseBrush = new SolidBrush(Color.Gray);
Brush CloseBrushSelected = new SolidBrush(Color.Black);
Font f = this.Font;
string title = this.tabControl1.TabPages[e.Index].Text;
e.Graphics.DrawString(title, f, TitleBrush, new PointF(r.X, r.Y));
if (e is DrawEventArgsCustom)
{
if (((DrawEventArgsCustom)e) != null && ((DrawEventArgsCustom)e).HoverTrue == true)
e.Graphics.DrawString("x", f, CloseBrushSelected, new PointF
(r.X + (this.tabControl1.GetTabRect(e.Index).Width - _imageLocation.X), _imageLocation.Y));
}
e.Graphics.DrawString("x", f, CloseBrush, new PointF
(r.X + (this.tabControl1.GetTabRect(e.Index).Width - _imageLocation.X), _imageLocation.Y));
}
catch (Exception ex)
{
}
}
private void tabControl1_MouseMove(object sender, MouseEventArgs e)
{
Rectangle mouseRect = new Rectangle(e.X, e.Y, 1, 1);
Graphics graphics = CreateGraphics();
for (int i = 0; i < tabControl1.TabCount; i++)
{
if (tabControl1.GetTabRect(i).IntersectsWith(mouseRect))
{
tabControl1_DrawItem(this, new DrawEventArgsCustom(hoverTrue: true, graphics, this.Font, mouseRect, i, DrawItemState.Focus));
}
}
}
class DrawEventArgsCustom : DrawItemEventArgs
{
public DrawEventArgsCustom(bool hoverTrue, Graphics graphics, Font font, Rectangle rect, int index, DrawItemState drawItemState)
: base(graphics, font, rect, index, drawItemState)
{
this.HoverTrue = hoverTrue;
this.Graph = graphics;
this.Fnt = font;
this.Rect = rect;
this.ind = index;
this.drawItemSt = drawItemState;
}
public bool HoverTrue { get; private set; }
public Graphics Graph { get; private set; }
public Font Fnt { get; private set; }
public Rectangle Rect { get; private set; }
public int ind { get; private set; }
public DrawItemState drawItemSt { get; private set; }
}
No need to create new Graphics objects like that, you should do all the drawings in the DrawItem event. For example in this context:
//a class level variable.
private int HoverIndex = -1;
private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
{
var g = e.Graphics;
var tp = tabControl1.TabPages[e.Index];
var rt = e.Bounds;
var rx = new Rectangle(rt.Right - 20, (rt.Y + (rt.Height - 12)) / 2 + 1, 12, 12);
if ((e.State & DrawItemState.Selected) != DrawItemState.Selected)
{
rx.Offset(0, 2);
}
rt.Inflate(-rx.Width, 0);
rt.Offset(-(rx.Width / 2), 0);
using (Font f = new Font("Marlett", 8f))
using (StringFormat sf = new StringFormat()
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center,
Trimming = StringTrimming.EllipsisCharacter,
FormatFlags = StringFormatFlags.NoWrap,
})
{
g.DrawString(tp.Text, tp.Font ?? Font, Brushes.Black, rt, sf);
g.DrawString("r", f, HoverIndex == e.Index ? Brushes.Black : Brushes.LightGray, rx, sf);
}
tp.Tag = rx;
}
Note that, now the Tag property of each TabPage control holds a rectangle for the x button.
In the MouseMove event iterate through the TabPages, cast the x rectangle from the Tag property, check if the x rectangle contains the current e.Location, and call Invalidate(); method of the TabControl to update the drawing:
private void tabControl1_MouseMove(object sender, MouseEventArgs e)
{
for (int i = 0; i < tabControl1.TabCount; i++)
{
var rx =(Rectangle)tabControl1.TabPages[i].Tag;
if (rx.Contains(e.Location))
{
//To avoid the redundant calls.
if (HoverIndex != i)
{
HoverIndex = i;
tabControl1.Invalidate();
}
return;
}
}
//To avoid the redundant calls.
if (HoverIndex != -1)
{
HoverIndex = -1;
tabControl1.Invalidate();
}
}
In the MouseLeave event invalidate if necessary:
private void tabControl1_MouseLeave(object sender, EventArgs e)
{
if (HoverIndex != -1)
{
HoverIndex = -1;
tabControl1.Invalidate();
}
}
And to close/dispose a page, handle the MouseUp event:
private void tabControl1_MouseUp(object sender, MouseEventArgs e)
{
for(int i = 0; i < tabControl1.TabCount; i++)
{
var rx = (Rectangle)tabControl1.TabPages[i].Tag;
if (rx.Contains(rx.Location)) //changed e.Location to rx.Location
{
tabControl1.TabPages[i].Dispose();
return;
}
}
}
Related Posts
TabControl with Close and Add Button
I have a panel that has a collection of custom drawn controls. I know how to programmically scroll the panel but the problem is how the controls draw when scrolling. when scrolling right the control shows as normal but when scrolling left it is not looking correctly. This just the start of the complete application so I just have some basic testing in place right now. Need to find a way for the control to draw correctly when scrolling.
Form code:
public partial class Form1 : Form
{
Panel pn;
private int location = 0;
public Form1()
{
InitializeComponent();
pn = new Panel()
{
Width = this.ClientRectangle.Width - 20,
Height = 120,
BackColor = Color.Black,
Left = 5,
Top = 20
};
pn.AutoScroll = false;
pn.VerticalScroll.Maximum = 100;
pn.HorizontalScroll.Maximum = this.ClientRectangle.Width - 100;
pn.VerticalScroll.Visible = false;
pn.HorizontalScroll.Visible = false;
pn.AutoScrollPosition = new Point(0, 0);
pn.AutoScroll = true;
this.KeyPreview = true;
this.KeyDown += new KeyEventHandler(keyPress);
for(int i = 0; i<10;i++)
{
CustomControl1 cc = null;
if (i % 2 != 0)
cc = new CustomControl1()
{
isOdd = true,
Width = 100,
Height = 100,
Left = (100*i)+5,
Top = 0
};
else
cc = new CustomControl1()
{
isOdd = false,
Width = 100,
Height = 100,
Left = (100 * i) + 5,
Top = 0
};
pn.Controls.Add(cc);
}
this.Controls.Add(pn);
}
private void keyPress(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.A:
if(location - 20 >0)
{
location -= 20;
pn.HorizontalScroll.Value = location;
}
else
{
location = 0;
pn.AutoScrollPosition = new Point(location, 0);
}
break;
case Keys.D:
if(location +20 < pn.HorizontalScroll.Maximum)
{
location += 20;
pn.HorizontalScroll.Value = location;
}
else
{
location = pn.VerticalScroll.Maximum;
pn.AutoScrollPosition = new Point(location, 0);
}
break;
}
foreach(Control c in pn.Controls)
{
c.Invalidate();
}
}
}
Control Code:
public partial class CustomControl1 : Control
{
public bool isOdd { get; set; }
public CustomControl1()
{
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs pe)
{
Graphics gr = pe.Graphics;
Rectangle rc = new Rectangle(pe.ClipRectangle.X,pe.ClipRectangle.Y,100,100);
Brush br = new SolidBrush(Color.Red);
if (isOdd)
br = new SolidBrush(Color.Yellow);
gr.FillEllipse(br, rc);
base.OnPaint(pe);
}
protected override void OnPaintBackground(PaintEventArgs pe)
{
base.OnPaintBackground(pe);
}
}
Don't clip your drawing:
//Rectangle rc = new Rectangle(pe.ClipRectangle.X, pe.ClipRectangle.Y, 100, 100);
Rectangle rc = new Rectangle(0, 0, 100, 100);
I've created a custom control in C#. A highly-simplified version of it is shown below:
class WellControl : Control
{
Pen circlePen = new Pen(Color.Black, 5);
Brush wellShader = new SolidBrush(Color.BlueViolet);
Brush wellBlanker = new SolidBrush(Color.LightGray);
public WellControl(int wellNum)
{
InitializeComponent();
}
private void DrawWell()
{
using (Graphics well = this.CreateGraphics())
{
this.Size = new Size(WellSize, WellSize);
if (this.selected)
{
well.FillEllipse(wellShader, ellipseCoords);
}
else
{
well.FillEllipse(wellBlanker, ellipseCoords);
}
well.DrawEllipse(circlePen, ellipseCoords);
using (Font wellNumberFont = new Font("Arial", 14, FontStyle.Bold))
{
well.DrawString(WellNum.ToString(), wellNumberFont, Brushes.Black, new Point(13, 13));
}
}
}
private void WellPaintEventHandler(object sender, EventArgs e)
{
DrawWell();
}
private void InitializeComponent()
{
this.SuspendLayout();
this.Paint += new System.Windows.Forms.PaintEventHandler(WellPaintEventHandler);
this.ResumeLayout();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
//dispose all the custom stuff
}
}
}
When I add it to a form, it renders properly (again, simplified example):
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
for (int i = 0; i < 4; i++)
{
WellControl newWell = new WellControl(i + 1);
newWell.Location = new Point(15, 50 * i);
newWell.Size = new System.Drawing.Size(45, 45);
this.Controls.Add(newWell);
}
}
}
I have another custom control, "Plate", which is intended to hold many "Wells". The code intended to draw the wells evenly across the plate probably sucks right now but I'm just trying to see something:
class PlateControl : Control
{
Pen blackPen = new Pen(Color.Black, 3);
public PlateControl()
{
this.Size = new Size(600, 800);
List<WellControl> plateWells = new List<WellControl>();
int column = 1;
int row = 0;
for (int i = 1; i <= 96; i++)
{
column = Convert.ToInt32(Math.Ceiling(Convert.ToDecimal(i / 8)));
row = i % 8;
WellControl newWell = new WellControl(i + 1);
newWell.Name = "wellControl" + i;
newWell.Location = new Point(column * 50, row * 50);
newWell.Size = new System.Drawing.Size(45, 45);
newWell.TabIndex = i;
newWell.WellSize = 45;
plateWells.Add(newWell);
newWell.Visible = true;
}
InitializeComponent();
}
private void InitializeComponent()
{
this.SuspendLayout();
this.Paint += new System.Windows.Forms.PaintEventHandler(PlatePaintEventHandler);
this.ResumeLayout();
}
private void DrawPlate()
{
using (Graphics plate = this.CreateGraphics())
{
Point topLeft = new Point(0, 0);
Point topRight = new Point(600, 0);
Point bottomRight = new Point(600, 400);
Point bottomLeft = new Point(0, 400);
plate.DrawLine(blackPen, topLeft, topRight);
plate.DrawLine(blackPen, topRight, bottomRight);
plate.DrawLine(blackPen, bottomRight, bottomLeft);
plate.DrawLine(blackPen, bottomLeft, topLeft);
}
}
private void PlatePaintEventHandler(object sender, EventArgs e)
{
DrawPlate();
}
}
If I add this control to a Winform using this.Controls.Add(new PlateControl()), the rectangle renders, but not the WellControls I added to the PlateControl in the constructor loop. What am I doing incorrectly?
You need to add List of WallControl to plate control.
public PlateControl()
{
this.Size = new Size(600, 800);
List<WellControl> plateWells = new List<WellControl>();
int column = 1;
int row = 0;
for (int i = 1; i <= 96; i++)
{
column = Convert.ToInt32(Math.Ceiling(Convert.ToDecimal(i / 8)));
row = i % 8;
WellControl newWell = new WellControl(i + 1);
newWell.Name = "wellControl" + i;
newWell.Location = new Point(column * 50, row * 50);
newWell.Size = new System.Drawing.Size(45, 45);
newWell.TabIndex = i;
newWell.WellSize = 45;
plateWells.Add(newWell);
newWell.Visible = true;
}
this.Controls.AddRange(plateWells.ToArray());
InitializeComponent();
}
I am creating dynamic text fields and storing Position and font etc details in an Arraylist. So for example if I click 3 times on Form I am generating 3 random numbers and showing it on clicked position on form. I have one selector button when it is clicked then adding more text functionality is disabled.
Now after when selector button is clicked and if I click ( MouseDown event) on any text then it should move along mouse until MouseUp event is not fired and place on new drop position.
After hours of struggling and searching I found This Solution, So I saved the position and checked with IsPointOnLine method but still its not draggable.
Thank you for any help.
Update: managed to get foreach on place but its still not dragging the selected element.
Form1.Class
public partial class Form1 : Form
{
private Point mouseDownPosition = new Point(0, 0);
private Point mouseMovePosition = new Point(0, 0);
private int mousePressdDown;
IList drawnItemsList = new List<DrawingData>();
private bool dragging;
private bool isSelectorClicked; // if selector button is clicked
DrawingData draggingText;
Random rnd;
int clicked = 0;
public Form1()
{
InitializeComponent();
this.rnd = new Random();
this.isSelectorClicked = false;
dragging = false;
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
mouseMovePosition = e.Location;
if (e.Button == MouseButtons.Left)
mousePressdDown = 1;
if (isSelectorClicked)
{
foreach (DrawingData a in drawnItemsList)
{
if (a.IsPointOnLine(e.Location, 5))
{
draggingText = a;
dragging = true;
}
}
}
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
mouseDownPosition = e.Location;
if (dragging)
{
draggingText.cur = mouseDownPosition;
this.Invalidate();
}
}
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
if (mousePressdDown == 1 && isSelectorClicked == false)
{
label1.Text = "X: " + mouseMovePosition.X.ToString();
label2.Text = "Y: " + mouseMovePosition.Y.ToString();
this.Invalidate();
DrawingData a = new DrawingData(mouseMovePosition, mouseDownPosition, rnd.Next().ToString(), FontStyle.Bold, 30, "Candara", Brushes.Blue);
drawnItemsList.Add(a);
this.clicked++;
}
mousePressdDown = 0;
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
if(drawnItemsList.Count != 0)
{
foreach (DrawingData a in drawnItemsList)
{
draw(e.Graphics, a);
}
if (mousePressdDown != 0)
{
draw(e.Graphics, mouseDownPosition, mouseMovePosition, FontStyle.Bold, 30, "Candara", Brushes.Blue);
}
}
}
private void draw(Graphics e, Point mold, Point mcur, FontStyle fontWeight, int fontSize, string fontName, Brush fontColor)
{
Pen p = new Pen(Color.Black, 2);
using (Font useFont = new Font(fontName, fontSize, fontWeight))
{
string header2 = rnd.Next().ToString();
RectangleF header2Rect = new RectangleF();
int moldX = mold.X - 5;
int moldY = mold.Y;
header2Rect.Location = new Point(moldX, moldY);
header2Rect.Size = new Size(600, ((int)e.MeasureString(header2, useFont, 600, StringFormat.GenericTypographic).Height));
e.DrawString(header2, useFont, fontColor, header2Rect);
}
}
private void draw(Graphics e, DrawingData a)
{
Pen p = new Pen(Color.Black, 2);
using (Font useFont = new Font(a.FontName, a.FontSize, a.FontWeight))
{
string header2 = rnd.Next().ToString();
RectangleF header2Rect = new RectangleF();
int moldX = a.old.X - 5;
int moldY = a.old.Y;
header2Rect.Location = new Point(moldX, moldY);
header2Rect.Size = new Size(600, ((int)e.MeasureString(header2, useFont, 600, StringFormat.GenericTypographic).Height));
e.DrawString(a.Rand, useFont, a.FontColor, header2Rect);
}
}
private void Select_button_Click(object sender, EventArgs e)
{
this.isSelectorClicked = true;
}
private void WriteNewText_button_Click(object sender, EventArgs e)
{
this.isSelectorClicked = false;
}
}
DrawingData.Class
[Serializable]
public class DrawingData
{
private Point Start; // mouseDown position
private Point End; // mouseUp poslition
private string randValue; // random data value
private FontStyle fontWeight;
private int fontSize;
private string fontName;
private Brush fontColor;
public DrawingData()
{
Start = new Point(0, 0);
End = new Point(0, 0);
randValue = String.Empty;
fontWeight = FontStyle.Bold;
}
public DrawingData(Point old, Point cur, string rand, FontStyle fs, int fSize, string fName, Brush fColor)
{
Start = old;
End = cur;
randValue = rand;
fontWeight = fs;
fontSize = fSize;
fontName = fName;
fontColor = fColor;
}
public float slope
{
get
{
return (((float)End.Y - (float)Start.Y) / ((float)End.X - (float)Start.X));
}
}
public float YIntercept
{
get
{
return Start.Y - slope * Start.X;
}
}
public bool IsPointOnLine(Point p, int cushion)
{
float temp = (slope * p.X + YIntercept);
if (temp >= (p.Y - cushion) && temp <= (p.Y + cushion))
{
return true;
}
else
{
return false;
}
}
public FontStyle FontWeight
{
get
{
return fontWeight;
}
set
{
fontWeight = value;
}
}
public int FontSize
{
get
{
return fontSize;
}
set
{
fontSize = value;
}
}
public string FontName
{
get
{
return fontName;
}
set
{
fontName = value;
}
}
public Brush FontColor
{
get
{
return fontColor;
}
set
{
fontColor = value;
}
}
public Point old
{
get
{
return Start;
}
set
{
Start = value;
}
}
public Point cur
{
get
{
return End;
}
set
{
End = value;
}
}
public string Rand
{
get
{
return randValue;
}
set
{
randValue = value;
}
}
}
SOLVED: I was missing these lines in my mouse move method:
m.Start = new Point(deltaStart.X + e.Location.X, deltaStart.Y + e.Location.Y);
m.End = new Point(deltaEnd.X + e.Location.X, deltaEnd.Y + e.Location.Y);
You should move stuff in Form1_MouseMove instead of Form1_MouseUp.
Find the element you want to move in the Arraylist and assign it new position.
Redraw the element.
Also you should use IList<DrawingData> instead of ArrayList
I faced with the problem with custom DataGridView. I want to draw a bottom line, but I can't avoid of drawing this line that remain on cells when I scrolling the grid.
public partial class GridTest : DataGridView
{
private static Color _gridColor = Color.FromArgb(219, 225, 232);
private int gridHeight;
private bool resizing;
private const int Xoffset = 5;
private const int Yoffset = 10;
Color cl1 = Color.FromArgb(255, 255, 255);
Color cl2 = Color.FromArgb(229, 233, 238);
Color cl3 = Color.FromArgb(234, 237, 242);
Color cl4 = Color.FromArgb(170, 186, 208);
private Color _clrColumnHeader;
public Color ColorColumnHeader
{
get { return _clrColumnHeader; }
set { _clrColumnHeader = value; }
}
public GridTest()
{
InitializeComponent();
Init();
}
public GridTest(IContainer container)
{
container.Add(this);
InitializeComponent();
Init();
}
private void Init()
{
var _headerHeight = 50;
ColumnHeadersHeight = _headerHeight;
BackgroundColor = Color.White;
RowTemplate.Height += 5;
AllowUserToAddRows = false;
AllowUserToDeleteRows = false;
AllowUserToResizeColumns = false;
AllowUserToResizeRows = false;
AutoResizeRows(DataGridViewAutoSizeRowsMode.AllCellsExceptHeaders);
AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
CellBorderStyle = DataGridViewCellBorderStyle.SingleHorizontal;
RowHeadersVisible = false;
MultiSelect = false;
ReadOnly = true;
AutoGenerateColumns = false;
EnableHeadersVisualStyles = false;
ShowCellErrors = false;
ShowEditingIcon = false;
ShowRowErrors = false;
}
private Blend gradientBlend()
{
float[] myFactors = { 0.0f, .00f, .8f, 1.0f };
float[] myPositions = { 0.0f, .4f, .8f, 1.0f };
var myBlend = new Blend {Factors = myFactors, Positions = myPositions};
return myBlend;
}
private void DrawGradientOnHeader(DataGridViewCellPaintingEventArgs e)
{
var newRect = new Rectangle(e.CellBounds.X+1, e.CellBounds.Y, e.CellBounds.Width -1, e.CellBounds.Height-1);
var gradient = new LinearGradientBrush(newRect, cl1, cl2, LinearGradientMode.Vertical);
gradient.Blend = gradientBlend();
e.Graphics.FillRectangle(gradient, newRect);
gradient.Dispose();
}
private static void DrawWhiteLine(DataGridViewCellPaintingEventArgs e, int x, int offset)
{
var brush = new SolidBrush(Color.White);
var pen = new Pen(brush);
int y = e.CellBounds.Y;
int x1 = x + offset;
int y1 = e.CellBounds.Height - 1;
var pt1 = new Point(x1, y);
var pt2 = new Point(x1, y1);
e.Graphics.DrawLine(pen, pt1, pt2);
brush.Dispose();
pen.Dispose();
}
private void DrawSeparators(DataGridViewCellPaintingEventArgs e)
{
DrawWhiteLine(e,e.CellBounds.Right,-1);
DrawWhiteLine(e, e.CellBounds.Left,1);
int x = e.CellBounds.X;
int y = e.CellBounds.Y;
int y1 = e.CellBounds.Height - 1;
var newRect2 = new Rectangle(x, y, 1, y1);
var gradient = new LinearGradientBrush(newRect2, cl3, cl4, LinearGradientMode.Vertical);
gradient.Blend = gradientBlend();
e.Graphics.FillRectangle(gradient, newRect2);
gradient.Dispose();
}
private static void DrawLines(DataGridViewCellPaintingEventArgs e)
{
var brush= new SolidBrush(Color.FromArgb(170, 186, 208));
var pen = new Pen(brush);
//Верхняя линяя над хидером
e.Graphics.DrawLine(pen, e.CellBounds.X, e.CellBounds.Top , e.CellBounds.Right, e.CellBounds.Top );
//Нижняя линия под хидером
e.Graphics.DrawLine(pen, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right, e.CellBounds.Bottom-1);
brush.Dispose();
pen.Dispose();
}
private void DrawText(DataGridViewCellPaintingEventArgs e)
{
var clr_font = _clrColumnHeader;
var rect = new Rectangle(e.CellBounds.X + Xoffset, e.CellBounds.Y + Yoffset, e.CellBounds.Width,
e.CellBounds.Height);
var formatFlags = TextFormatFlags.WordBreak;
if (e.Value != null)
{
try
{
TextRenderer.DrawText(e.Graphics, (String)e.Value, e.CellStyle.Font, rect, clr_font, formatFlags);
}
catch
{
TextRenderer.DrawText(e.Graphics, "", e.CellStyle.Font, rect, clr_font, formatFlags);
}
}
}
private void EraseTheCell(DataGridViewCellPaintingEventArgs e)
{
using (Brush backColorBrush = new SolidBrush(e.CellStyle.BackColor))
{
e.Graphics.FillRectangle(backColorBrush, e.CellBounds);
}
}
protected override void OnColumnWidthChanged(DataGridViewColumnEventArgs e)
{
base.OnColumnWidthChanged(e);
Invalidate();
}
private int oldRowIndex = 0;
protected override void OnCurrentCellChanged(EventArgs e)
{
base.OnCurrentCellChanged(e);
if (oldRowIndex != -1)
{
InvalidateRow(oldRowIndex);
}
oldRowIndex = CurrentCellAddress.Y;
}
protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
{
base.OnCellPainting(e);
if (e.RowIndex == -1) // Рисуем ColumnHeader
{
EraseTheCell(e);
DrawGradientOnHeader(e);
DrawSeparators(e);
DrawText(e);
DrawLines(e);
e.Handled = true;
}
//e.CellStyle.BackColor = Color.White;
}
protected override void PaintBackground(Graphics graphics, Rectangle clipBounds, Rectangle gridBounds)
{
base.PaintBackground(graphics, clipBounds, gridBounds);
var brush = new SolidBrush(Color.Black);
var pen = new Pen(brush);
var y_crd = clipBounds.Bottom - 10;
var x_crd = clipBounds.Right;
graphics.FillRectangle(brush, clipBounds);
var newbounds = new Rectangle
{
X = clipBounds.X,
Y = clipBounds.Y,
Width = clipBounds.Width,
Height = clipBounds.Height - 1
};
var brushWhite = new SolidBrush(Color.White);
graphics.FillRectangle(brushWhite, newbounds);
//graphics.DrawLine(pen, 0, y_crd, x_crd, y_crd);
brush.Dispose();
pen.Dispose();
}
}