I want to include the colored panel below into my form:
For this I have created custom panel which will change Border color based on Radio Button selection. My panel code is
InfoPanel.cs
class InfoPanel : Panel
{
private Color colorBorder = Color.Transparent;
public InfoPanel()
: base()
{
this.SetStyle(ControlStyles.UserPaint, true);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.DrawRectangle(
new Pen(
new SolidBrush(colorBorder), 2),
e.ClipRectangle);
e.Graphics.DrawLine(new Pen(new SolidBrush(colorBorder), 0), 50, 0, 50, 50); //drawing a line to split the child & parent info panel
}
public Color BorderColor
{
get
{
return colorBorder;
}
set
{
colorBorder = value;
}
}
}
In my form,
1. created one parent Info Panel
2. created one child panel with Picture box
3. One label in parent info panel to show the information
Now for the parent panel I am changing the colors [back, border] & text based on user selection & for child panel I am not changing border color but updating back color based on user selection.
Below is the code for changing the panel colors, image, text update:
private void rbIPAddress_CheckedChanged(object sender, EventArgs e)
{
if (rbIPAddress.Checked)
{
ParentInfoPanel.BackColor = System.Drawing.ColorTranslator.FromHtml("#FFFFEE");
ParentInfoPanel.BorderColor = System.Drawing.ColorTranslator.FromHtml("#DADA85");
ChildInfoPanel.BackColor = System.Drawing.ColorTranslator.FromHtml("#F6F6D8");
InfoPanelPictureBox.Image = Template.InfoPanelInfoImage;
Infolabel.Text = "IP Address is already configured. You can switch to Forward Lookup Zone by choosing other configuration. *IP Address \ncan be either LB IP Address.";
txtBoxIPAddress.Enabled = true;
textBoxPort.Enabled = true;
}
else
{
Infolabel.Text = "";
txtBoxIPAddress.Text = "";
txtBoxIPAddress.Enabled = false;
textBoxPort.Enabled = false;
}
}
private void rbForwardLookupZone_CheckedChanged(object sender, EventArgs e)
{
if (rbForwardLookupZone.Checked)
{
ParentInfoPanel.BackColor = System.Drawing.ColorTranslator.FromHtml("#FFFFEE");
ParentInfoPanel.BorderColor = System.Drawing.ColorTranslator.FromHtml("#DADA85");
ChildInfoPanel.BackColor = System.Drawing.ColorTranslator.FromHtml("#F6F6D8");
InfoPanelPictureBox.Image = Template.InfoPanelInfoImage;
Infolabel.Text = "Forward Lookup Zone is already configured. You can switch to IP Address by choosing other configuration and \nchanging port number will affect Firewall rules.";
textBoxControlPlane.Enabled = true;
if (string.IsNullOrEmpty(textBoxControlPlane.Text))
{
textBoxControlPlane.Text = Constants.DefaultControlPlaneDomain;
}
}
else
{
Infolabel.Text = "";
textBoxControlPlane.Text = "";
textBoxControlPlane.Enabled = false;
}
}
Note: used next line character to display label text in multiple line
Output: Everything is ok but in the end of label text I am getting another rectangle box. I'm wondering why is showing like this? Am I doing wrong? Please help me on this.
The issue is that you're using e.ClipRectangle. It informs you which portion of the control needs to be redrawn. This is sometimes only a small part of the control rather than the whole thing (in your case the area of the extra rectangle). Always draw the control's full rectangle instead.
Also, you must dispose of both the Pen and SolidBrush. Failing to do so causes memory leaks. Utilize the using statement.
using(SolidBrush brush = new SolidBrush(colorBorder))
using(Pen pen = new Pen(brush, 2))
{
e.Graphics.DrawRectangle(pen, new Rectangle(0, 0, this.ClientSize.Width - 1, this.ClientSize.Height - 1));
e.Graphics.DrawLine(pen, 50, 0, 50, 50);
}
Related
I am creating a project that needs to have a vertical scroll bar with multiple pictures like the server explorer in discord:
For example:
how can I mimic in WinForms in C# (not only having pictures scrolling but also the pictures can have events attached to them?
First you need add a Parent Panel, i'm used the pnServers.
Set property value:
AutoScroll = True;
On Code Behind you can create a List of Rounded Pictures.
private void DiscordServerBarExample_Load(object sender, System.EventArgs e)
{
// Example, in your case this looping is based on return (Database, Api, ...).
for (int i = 1; i <= 10; i++)
{
Panel pnServer = new Panel()
{
Dock = DockStyle.Top,
Height = pnServers.Width,
Padding = new Padding(10)
};
RoundedPictureBox serverImage = new RoundedPictureBox()
{
SizeMode = PictureBoxSizeMode.CenterImage,
Dock = DockStyle.Fill
};
serverImage.Image = Properties.Resources._255352;
pnServer.Controls.Add(serverImage);
pnServers.Controls.Add(pnServer);
}
}
Rounded Picture Box Code:
public class RoundedPictureBox : PictureBox
{
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
using (GraphicsPath gp = new GraphicsPath())
{
gp.AddEllipse(0, 0, Width - 1, Height - 1);
Region rg = new Region(gp);
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.DrawEllipse(new Pen(new SolidBrush(this.BackColor), 1), 0, 0, this.Width - 1, this.Height - 1);
Region = rg;
}
}
}
And this is final result.
I am having a problem witth visual studio. I created a menustrip with different menus and some contain separators. I want the theme of the program to be dark so I changed the color of all buttons to black background and white text.
however I cannot change the separators' colors. They are white background and black line. I tried from properties - not working. I tried with code - also not working. Can anyone help me?
Also I want to ask how to change the color of the outline of the buttons? it's currently white.
There's no need to create a new separator , just create a color table :
public class MyCustomColors: ProfessionalColorTable
{
public override Color SeparatorLight
{
get { return Color.FromArgb(100, 100, 100); }
}
public override Color SeparatorDark
{
get { return Color.FromArgb(100, 100, 100); }
}
}
}
then use it like :
menu_control.Renderer = new ToolStripProfessionalRenderer(new MyCustomColors());
The default toolstrip renderer ignores the BackColor property and uses hard-coded colors.
so write a custom class as below:
public class CustomToolStripSeparator : ToolStripSeparator
{
public CustomToolStripSeparator()
{
Paint += CustomToolStripSeparator_Paint;
}
private void CustomToolStripSeparator_Paint(object sender, PaintEventArgs e)
{
// Get the separator's width and height.
ToolStripSeparator toolStripSeparator = (ToolStripSeparator)sender;
int width = toolStripSeparator.Width;
int height = toolStripSeparator.Height;
//Color foreColor = Color.Blue;
Color backColor = Color.Yellow;
// Fill the background.
e.Graphics.FillRectangle(new SolidBrush(backColor), 0, 0, width, height);
// Draw the line.
//e.Graphics.DrawLine(new Pen(foreColor), 4, height / 2, width - 4, height / 2);
}
}
and inside your form_load method apply your custom toolstripseparator:
private void Form1_Load(object sender, EventArgs e)
{
ToolStripSeparator toolStripSeparator1 = new CustomToolStripSeparator();
ToolStripSeparator toolStripSeparator2 = new CustomToolStripSeparator();
ToolStripSeparator toolStripSeparator3 = new CustomToolStripSeparator();
this.fileToolStripMenuItem.DropDownItems.Add("Save Project");
this.fileToolStripMenuItem.DropDownItems.Add(toolStripSeparator1);
this.fileToolStripMenuItem.DropDownItems.Add("Reload Project");
this.fileToolStripMenuItem.DropDownItems.Add(toolStripSeparator2);
this.fileToolStripMenuItem.DropDownItems.Add("Close Project");
this.fileToolStripMenuItem.DropDownItems.Add(toolStripSeparator3);
this.fileToolStripMenuItem.DropDownItems.Add("New Window");
}
I have a winform that starts out with a sizable border around it. On the form is a button which, when pressed, changes the form to border style none.
The problem is that then the inner part of the form moves up and to the left slightly. I want to make it that, no matter what border is used, the "inner" part of the form will always stay in the same spot (note: but I do still want the form to be moved around when it has a movable border selected)
Thanks.
The Borderless form moves up and slightly left because thats the location that the form currently has,you need to count for the border.To achieve the result you are after you need to reassign the location property and to do that you need to account for the client size and the whole size(with border),the code i think is simple and it will be self-explanatory i believe:
private void button1_Click(object sender, EventArgs e)
{
var X = (this.Size.Width - this.ClientRectangle.Width) / 2;
var Y = (this.Size.Height - this.ClientRectangle.Height) - X;
Point p = new Point(Location.X + X, Location.Y + Y);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Location = p;
}
Another option is to set the padding on the parent that contains the panel with the border. E.g.
public class Form10 : Form {
Button btn = new Button { Text = "Button", Location = new Point(100, 100) };
Panel border = new Panel { Dock = DockStyle.Fill, BorderStyle = BorderStyle.Fixed3D };
public Form10() {
Controls.Add(border);
border.Controls.Add(btn);
btn.Click += delegate {
if (border.BorderStyle == BorderStyle.Fixed3D) {
border.BorderStyle = BorderStyle.None;
border.Parent.Padding = new Padding(2);
}
else {
border.BorderStyle = BorderStyle.Fixed3D;
border.Parent.Padding = new Padding(0);
}
};
}
}
My form has two objects: a background image that takes up the entire screen, and a dragable dialog control that only takes up a portion of the screen. I am using Mouse events for dragging and dropping the dialog control within the background image.
My problem is that while dragging, there is a copy of the control that is visible at it's previous location.
What is causing this shadow copy to appear, and how can I prevent it from happening?
My code looks something like this:
private void dialog_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
_dialogDragStart = e.Location;
dialog.MouseMove += new MouseEventHandler(dialog_MouseMove);
}
}
private void dialog_MouseUp(object sender, MouseEventArgs e)
{
dialog.MouseMove -= new MouseEventHandler(dialog_MouseMove);
_isDragging.Value = false;
}
private void dialog_MouseMove(object sender, MouseEventArgs e)
{
var difference = new Point(e.Location.X - _dialogDragStart.X, e.Location.Y - _dialogDragStart.Y);
if (!_isDragging.Value)
{
if (Math.Abs(difference.X) > SystemInformation.DragSize.Width || Math.Abs(difference.Y) > SystemInformation.DragSize.Height)
{
_isDragging.Value = true;
}
}
else if (_isDragging.Value && !difference.IsEmpty)
{
DialogOffset = GetValidDialogOffset(DialogOffset.X + difference.X, DialogOffset.Y + difference.Y);
this.Invalidate();
this.Update();
}
}
It should be noted that this entire UserControl contains a custom OnPaint event. The Paint event recalculates the Size and Location of the Dialog before painting it in a custom format. To get this working, I have simply adjusted the Location calculation to include the DialogOffset.
const int padding = 1;
const int shadowDepth = 3;
const int roudeCornerRadius = 5;
private void Paint(Graphics g, Rectangle clipRect)
{
try
{
dialog.Size = GetSize();
dialog.Location = new Point(
((backgroundImage.Width - dialog.Width) / 2) + DialogOffset.X,
((backgroundImage.Height - dialog.Height) / 2) + DialogOffset.Y);
if (Image != null && !backgroundImage.ClientRectangle.IsEmpty)
{
Rectangle imageBounds = new Rectangle(Point.Empty, Image.Size);
using (BufferedGraphics buffer = BufferedGraphicsManager.Current.Allocate(g, backgroundImage.ClientRectangle))
{
using (Bitmap img = ((Bitmap)backgroundImage).Clone(imageBounds, PixelFormat.Format16bppArgb1555) as Bitmap)
{
buffer.Graphics.Clear(Color.White);
buffer.Graphics.DrawImage(img,backgroundImage.ClientRectangle, imageBounds, GraphicsUnit.Pixel);
buffer.Render(g);
}
}
}
//Create Rectangles
Rectangle outerRect = dialog.ClientRectangle;
Rectangle innerRect = new Rectangle(padding, padding, outerRect.Width - (padding + shadowDepth), outerRect.Height - (padding + shadowDepth));
//create Paths
using (GraphicsPath innerPath = new GraphicsPath())
{
GraphicsHelper.GetRoundedRect(innerPath, innerRect, roudeCornerRadius, 1, 1);
//Assign outer rounded rectangle to the dialog's region property
Region region = new Region(innerPath);
if (dialog.Region != null)
dialog.Region.Dispose();
dialog.Region = region;
}
}
catch (Exception ex)
{
// Log error
}
}
I've seen suggestions to set the DoubleBufferred property to true, however its explicitly set to false in the existing code, and setting it to true causes no update at all while dragging.
I've tried taking a screenshot of the problem, however all screenshots only show one copy of the dialog control being dragged, even though I can clearly see a 2nd copy of the control on my screen while dragging.
What can be causing this, and how can I fix it?
I am having a problem on my extendedtabcontol class, I cannot get rid of the dotted box or the visual style box on the selected tab. I have my own DrawItem (see below), I have overridden several methods from the tabcontrol and I have even overridden the WM_SETFOCUS and WM_PAINT in WndProc but the box and highlight will not go away. Is there anyway to turn them off (the box or visual style) or a simple way to draw over them / stop them drawing?
The user can tell which tab is selected because it is drawn in black when the others are grey.
protected void OnDrawItem(object sender, DrawItemEventArgs e)
{
// VisualStyleRenderer renderer =
// new VisualStyleRenderer(VisualStyleElement.Tab.TabItem.Disabled);
DrawItemState ds = e.State;
SolidBrush mybrush = new SolidBrush(Color.FromArgb(255, 151, 0, 11));
Rectangle tabArea2 = new Rectangle(0, 0, this.Size.Width+10, this.Size.Height+10);
//renderer.DrawBackground(e.Graphics, tabArea2);
e.Graphics.FillRectangle(mybrush, tabArea2);
int i = 0;
foreach (TabPage tb in this.TabPages)
{
Rectangle tabArea = this.GetTabRect(i);
Point newp = new Point(tabArea.Location.X,tabArea.Location.Y + 2);
tabArea.Location = newp;
if (this.SelectedIndex != i)
{
RectangleF tabTextArea = (RectangleF)this.GetTabRect(i);
e.Graphics.DrawImage(global::Config.Properties.Resources.Tab2, tabArea.Location);
}
else
{
e.Graphics.DrawImage(global::Config.Properties.Resources.Tab1, tabArea.Location);
}
SizeF size = e.Graphics.MeasureString(tb.Name.ToString().Trim(), drawFont);
PointF pf = new PointF();
pf.X = tabArea.X + (tabArea.Width / 2) - (size.Width/2);
pf.Y = tabArea.Y + (tabArea.Height / 2) - (size.Height/2);
e.Graphics.DrawString(tb.Name.ToString().Trim(), drawFont, drawBrush, pf);
i++;
}
}
I would post an image but I don't have the reputation.
Similar question for example:
Can I remove the dotted focus rectangle over tabs on a TabControl?