I have a panel and a richTextBox placed at the bottom corner of the panel. Panel takes text from richTextBox and Draws using DrawString() on the panel using its paint event.
When the panel is filled it does not auto-scroll the panel even if autoscroll=true.
How to enable scrollings to a paint event handling panel?
How to reflect the scrolling of richTexBox in a panel(if richtextbox is scrolled to some extent, the panel should also be scrolled to the same extent?)
In short the visible content of richtextbox must be visible in the panel exactly.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Drawing.Drawing2D;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
namespace TextFormatter
{
public partial class Form1 : Form
{
//int scrol;
public Form1()
{
InitializeComponent();
//Set Double Buffering
panel1.GetType().GetMethod("SetStyle",
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.NonPublic)
.Invoke(panel1, new object[] {
System.Windows.Forms.ControlStyles.UserPaint |
System.Windows.Forms.ControlStyles.AllPaintingInWmPaint |
System.Windows.Forms.ControlStyles.DoubleBuffer, true });
}
class myFont
{
public int size;
public string family;
public Color c;
}
myFont f = new myFont();
private void Form1_Load(object sender, EventArgs e)
{
}
private void UpdateStatus()
{
panel1.Refresh();
}
delegate void UpdateStatusInvoker();
private void panel1_Paint_1(object sender, PaintEventArgs e)
{
Point P = new Point();
int w = this.ClientSize.Width;
int h = this.ClientSize.Height;
P.X = w - 180;
P.Y = h - 52;
richTextBox1.Location = (P);
Graphics g = e.Graphics;
Brush b;
b = new SolidBrush(f.c);
if (f.c.IsEmpty)
{
b = new SolidBrush(Color.Brown);
}
Point p = new Point();
p.X = 100;
p.Y = 100;
Font ff = new Font(f.family, f.size | 20);
g.DrawString("" + richTextBox1.Text, ff, b, p);
// richTextBox1.AppendText(
b.Dispose();
// g.Dispose();
}
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
// Invalidate();
this.Invoke(new UpdateStatusInvoker(UpdateStatus));
}
private void richTextBox1_VScroll(object sender, EventArgs e)
{
// same scrolling must be applied on panel.
}
private void panel1_Scroll(object sender, ScrollEventArgs e)
{
// control the scrolling of graphical content of the panel
}
}
}
Related
I have a problem with scrolling in WinForm C# in Panel AutoScroll with Dynamic created buttons.
On Form1.cs Created a Panel1 with Manual Designed Buttons (6 or 7) and set autoscroll= true. You can click.down and scroll anywhere in panel1 as it scrolls the way it should. But if I create it dynamic buttons (as coded) it does not work. I click.down on buttons and i can not scroll. I'm able to scroll if I click outside buttons ie. in the Panel1 and it works. I need to click anywhere!
using System;
using System.Drawing;
using System.Windows.Forms;
namespace ScrollTouch
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
new TouchScroll(panel1);
}
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++)
{
Button b = new Button();
b.Text = i.ToString();
b.Size = new Size(100, 90);
b.Location = new Point(i*140, 0);
panel1.Controls.Add(b);
}
}
}
}
This is just a class TouchScroll.c (class)
using System;
using System.Drawing;
using System.Windows.Forms;
namespace ScrollTouch
{
public class TouchScroll
{
private Point mouseDownPoint;
private Panel parentPanel;
public TouchScroll(Panel panel)
{
parentPanel = panel;
AssignEvent(panel);
}
private void AssignEvent(Control control)
{
control.MouseDown += MouseDown;
control.MouseMove += MouseMove;
foreach (Control child in control.Controls)
{
AssignEvent(child);
}
}
private void MouseMove(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left)
return;
Point pointDifference = new Point(Cursor.Position.X - mouseDownPoint.X, Cursor.Position.Y + mouseDownPoint.Y);
if ((mouseDownPoint.X == Cursor.Position.X) && (mouseDownPoint.Y == Cursor.Position.Y))
return;
Point currAutos = parentPanel.AutoScrollPosition;
parentPanel.AutoScrollPosition = new Point(Math.Abs(currAutos.X) + pointDifference.X, Math.Abs(currAutos.Y) + pointDifference.Y);
mouseDownPoint = Cursor.Position;
}
private void MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
this.mouseDownPoint = Cursor.Position;
}
}
}
I've created a windows form that when I click on a button, it shows a panda moving.
It works when I add one Panda, but I want another panda to appear on button click. I'm trying to when I click the button for another time to show another panda! When I click the button my panda disappear and reappear again from it's start point and starts moving!
(for example clicking the button 3 times = having 3 pandas moving in my form)
That's the code for the class called "panda":
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
namespace test_moving_pic
{
class panda
{
public Image img_panda;
public Rectangle rect_panda;
public panda(Image img, Rectangle rect)
{
this.img_panda = img;
this.rect_panda = rect;
}
}
}
and this is the code that I used for my Form:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace test_moving_pic
{
public partial class Form1 : Form
{
Image image;
Rectangle rect;
int direction = 3;
public Form1()
{
InitializeComponent();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
if (image != null && rect != null)
g.DrawImage(image, rect);
}
private void timer1_Tick(object sender, EventArgs e)
{
rect.X += this.direction;
rect.Y += this.direction;
if (rect.X <= 100 && rect.Y <= 100)
{
rect.X += this.direction;
rect.Y += this.direction;
}
else
{
rect.Y += this.direction;
if (rect.Y >= 100)
{
rect.Y = 100;
rect.X += this.direction;
}
}
Invalidate();
}
private void button1_Click(object sender, EventArgs e)
{
panda p = new panda(Image.FromFile("C:\\Users\\hsnha\\OneDrive\\Desktop\\Panda.png"), new Rectangle(20, 20, 70, 70));
image = p.img_panda;
rect = p.rect_panda;
}
}
}
Try this:
public partial class Form1 : Form
{
List<panda> pandaList = new List<panda>();
int direction = 3;
class panda
{
public Image img_panda;
public Rectangle rect_panda;
public panda(Image img, Rectangle rect)
{
this.img_panda = img;
this.rect_panda = rect;
}
}
public Form1()
{
InitializeComponent();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
foreach (panda p in pandaList)
g.DrawImage(p.img_panda, p.rect_panda);
}
private void timer1_Tick(object sender, EventArgs e)
{
foreach (panda p in pandaList)
{
p.rect_panda.X += this.direction;
p.rect_panda.Y += this.direction;
if (p.rect_panda.X <= 100 && p.rect_panda.Y <= 100)
{
p.rect_panda.X += this.direction;
p.rect_panda.Y += this.direction;
}
else
{
p.rect_panda.Y += this.direction;
if (p.rect_panda.Y >= 100)
{
p.rect_panda.Y = 100;
p.rect_panda.X += this.direction;
}
}
}
Invalidate();
}
private void button1_Click(object sender, EventArgs e)
{
pandaList.Add(new panda(Image.FromFile(#"C:\Users\hsnha\OneDrive\Desktop\Panda.png"), new Rectangle(20, 20, 70, 70)));
}
}
Form1_Paint is only going to draw one panda. You need to somehow save all the pandas you've created, and draw all of the pandas in the Paint method! You also need to update the position of all pandas in Tick.
For example:
Define a member in your class List<panda> pandas; and
private void button1_Click(object sender, EventArgs e)
{
panda p = new panda(Image.FromFile("C:\\Users\\hsnha\\OneDrive\\Desktop\\Panda.png"), new Rectangle(20, 20, 70, 70));
pandas.Add(p);
}
private void timer1_Tick(object sender, EventArgs e)
{
foreach (panda p in pandas)
{
Rectangle rect = p.rect_panda;
// Fix the rect like before
}
}
And similarly for Draw, loop over the pandas and draw each. Does this help you get unstuck?
This little program opens a windows form and draws 70 red rectangles, where the user clicks on the form.
Every time the user clicks, the rectangles disappear, and new ones are drawn on the new click-Point.
I want to make the rectangles to stay when the user clicks and draws a new set of rectangles.
How do i do that?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace tegnRektangel
{
public partial class Form1 : Form
{
int x;
int y;
bool mouseClicked = false;
Graphics g = null;
public Form1()
{
InitializeComponent();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
}
private void Form1_Resize(object sender, EventArgs e)
{
Invalidate();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
if (mouseClicked)
{
g = panel1.CreateGraphics();
paintRectangel();
}
}
private void paintRectangel()
{
for (int i = 1; i <= 70; i++)
{
g.DrawRectangle(Pens.Red, x - 50-i*5, y - 40-i*5, 100, 80);
}
g.Dispose();
}//end paint
private void panel1_MouseClick(object sender, MouseEventArgs e)
{
mouseClicked = true;
Point clickPoint = new Point(e.X,e.Y);
x = clickPoint.X;
y = clickPoint.Y;
panel1.Invalidate();
}
}
}
From MSDN:
The Graphics object that you retrieve through the CreateGraphics
method should not normally be retained after the current Windows
message has been processed, because anything painted with that object
will be erased with the next WM_PAINT message.
You can work around it like this:
In the click event, add the (x, y) coordinate to a list of coordinates.
In the paint event, iterate all these (x, y) coordinates and paint each rectangle.
Here is some code to demonstrate creating rectangles for each click, storing them, and painting all stored rectangles.
public partial class Form1 : Form
{
private List<Rectangle> Rectangles { get; set; }
public Form1()
{
InitializeComponent();
Rectangles = new List<Rectangle>();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
if (Rectangles.Count > 0)
e.Graphics.DrawRectangles(Pens.Red, Rectangles.ToArray());
}
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
for (int i = 1; i <= 70; i++)
{
Rectangles.Add(new Rectangle(e.X - 50 - i * 5, e.Y - 40 - i * 5, 100, 80));
}
Invalidate();
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace UTUResultWithCoordinates
{
public partial class GetCoordinates : Form
{
private string sem;
private string branch;
private int mouseisdown = 0;
private int recx = 0;
private int recy = 0;
private int mousemovingwhilepressed = 0;
public GetCoordinates()
{
InitializeComponent();
}
public GetCoordinates(string p, string p_2)
{
// TODO: Complete member initialization
InitializeComponent();
branch = p;
sem = p_2;
pictureBox1.Controls.Add(pictureBox2);
pictureBox2.Location = new Point(0, 0);
pictureBox2.BackColor = Color.Transparent;
pictureBox2.Width = 1191;
pictureBox2.Height = 842;
}
private void GetCoordinates_Load(object sender, EventArgs e)
{
pictureBox1.ImageLocation = #"D:\DotNet\UTUResultWithCoordinates\UTUResultWithCoordinates\bin\Debug\ComputerScience6.jpg";
}
private void pictureBox2_Paint(object sender, PaintEventArgs e)
{
if (mouseisdown == 1 && mousemovingwhilepressed==1)
{
System.Drawing.Graphics graphicsObj;
graphicsObj = this.CreateGraphics();
Pen myPen = new Pen(System.Drawing.Color.Blue, 100);
Rectangle myRectangle = new Rectangle(recx, recy, 20, 20);
e.Graphics.DrawRectangle(myPen, myRectangle);
}
}
private void pictureBox2_MouseDown(object sender, MouseEventArgs e)
{
mouseisdown = 1;
recx = e.X;
recy = e.Y;
pictureBox2.CreateGraphics();
}
private void pictureBox2_MouseMove(object sender, MouseEventArgs e)
{
label1.Text = e.X + "," + e.Y;
mousemovingwhilepressed = 1;
recx = e.X;
recy = e.Y;
pictureBox2.CreateGraphics();
}
private void pictureBox2_MouseUp(object sender, MouseEventArgs e)
{
mousemovingwhilepressed = 0;
mouseisdown = 0;
pictureBox2.CreateGraphics();
}
}
}
I have created a pictureBox1 in which an image is displayed. Then I have created a pictureBox2 inside it so that I can paint on that image a rectangle by dragging the mouse. But nothing is happening on clicking the mouse. What is the error?
Calling CreateGraphics does not trigger the painting of the PictureBox.
Use Invalidate to cause a redraw.
For a full example see: How to select an area on a PictureBox.Image with mouse in C#
Side notes:
Calling InitializeControl in a method other than the constructor is not a good idea.
when you need a boolean use a boolean, not an integer.
Objects that implement IDisposable (such as Pen) should be created as few times as possible and be disposed when no longer needed/used.
I am trying to show multicolored text in a datagridviewcell and I'm almost there.
But found a little bit problem with double clicking the column divider.
When I double click the column divider, a portion of cell background color is not painted
properly. What am I forgetting to do with my code? Please suggest me.
Here is my code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace MulticoloredGridViewTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
dataGridView1.Rows.Add("niaz,rahim,azme,niaz,rahim,azme", "123,677,111", "dhaka,dhaka,dhaka");
}
private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.RowIndex >= -1)
{
// Rectangle newRect = new Rectangle(e.CellBounds.X + 1, e.CellBounds.Y + 1, e.CellBounds.Width - 1, e.CellBounds.Height - 1);
e.Paint(e.ClipBounds, DataGridViewPaintParts.All & ~DataGridViewPaintParts.ContentForeground);
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
Point startPoint = e.CellBounds.Location;
if (e.Value != null)
{
string[] dataList = e.Value.ToString().Split(',');
foreach (string data in dataList)
{
SizeF tmpSize = e.Graphics.MeasureString(data.Trim(), e.CellStyle.Font);
Rectangle txtRegion = new Rectangle(startPoint, new Size((int)(tmpSize.Width + 3), e.CellBounds.Height));
Color clr = new Color();
if (data.Trim().Contains("rahim"))
clr = Color.Red;
else
clr = Color.Black;
using (SolidBrush br = new SolidBrush(clr))
{
e.Graphics.DrawString(data.Trim(), e.CellStyle.Font, br, txtRegion, StringFormat.GenericDefault);
}
startPoint = new Point(startPoint.X+txtRegion.Width+1, e.CellBounds.Location.Y);
}
e.Handled = true;
}
}
}
private void button1_Click(object sender, EventArgs e)
{
string[] cell = textBox1.Text.Split(',');
string value = dataGridView1.Rows[int.Parse(cell[0])].Cells[int.Parse(cell[1])].Value.ToString();
label1.Text = value;
}
private void dataGridView1_ColumnDividerDoubleClick(object sender, DataGridViewColumnDividerDoubleClickEventArgs e)
{
dataGridView1.Columns[e.ColumnIndex].DividerWidth = dataGridView1.CurrentCell.Value.ToString().Length + 10;
dataGridView1.Invalidate();
}
}
}
try to expand all columns and then apply painting.
something like this:
private void btnAutoResizeContactNameColumn_Click(object sender, EventArgs e)
{
// Perform Auto Resize on Contact column
this.ultraGrid1.DisplayLayout.Bands[0].Columns["ContactName"].PerformAutoResize();
}
check out this link