Horizontal divider of the StatusStrip - c#

In a Windows.Forms application, I want to change the color of the horizontal divider line of the StatusStrip, or make this line invisible. Any ideas?
This is the I'm referring to:
file: Program.cs
using System;
using System.Data;
using System.Drawing;
using System.Data.Linq;
using System.Windows.Forms;
namespace test {
class Program {
[STAThread]
static void Main() {
Application.Run(new FormMain());
}
}
}
file: FormMain.cs
using System;
using System.Data;
using System.Drawing;
using System.Data.Linq;
using System.Windows.Forms;
namespace test {
class Vars {
public class Colors {
public static Color BackRed = Color.FromArgb(040, 000, 000);
public static Color ForeRed = Color.FromArgb(240, 120, 120);
public static Color BackGrn = Color.FromArgb(000, 040, 000);
public static Color ForeGrn = Color.FromArgb(120, 240, 120);
public static Color BackBlu = Color.FromArgb(000, 000, 040);
public static Color ForeBlu = Color.FromArgb(120, 120, 240);
}
}
class FormMain : Form {
MenuStrip menuStrip = new MenuStrip();
StatusStrip statusStrip = new StatusStrip();
public FormMain() {
this.FormMain_Setup();
}
private void FormMain_Setup() {
this.Top = 20;
this.Left = 20;
this.Width = 1200;
this.Height = 675;
this.BackColor = Vars.Colors.BackBlu;
this.ForeColor = Vars.Colors.ForeBlu;
this.MaximizeBox = false;
this.StartPosition = FormStartPosition.Manual;
this.FormBorderStyle = FormBorderStyle.Fixed3D;
this.KeyDown += FormMain_KeyDown;
this.FormMain_MenuStrip_Setup();
this.FormMain_StatusStrip_Setup();
}
private void FormMain_StatusStrip_Setup() {
this.statusStrip.Height = 30;
this.statusStrip.AutoSize = false;
this.statusStrip.BackColor = Vars.Colors.BackRed;
this.statusStrip.ForeColor = Vars.Colors.ForeRed;
this.statusStrip.SizingGrip = false;
this.Controls.Add(statusStrip);
}
private void FormMain_MenuStrip_Setup() {
this.menuStrip.Height = 30;
this.menuStrip.AutoSize = false;
this.menuStrip.BackColor = Vars.Colors.ForeGrn;
this.menuStrip.ForeColor = Vars.Colors.BackGrn;
this.Controls.Add(menuStrip);
}
private void FormMain_KeyDown(object sender, KeyEventArgs e) {
this.FormMain_Exit();
}
private void FormMain_Exit() {
this.Close();
}
}
}

I found this 6+ years old question while I was googling around. I don't think it remains a problem for the OP. Just for the future readers.
When you add a StatusStrip instance by the designer or code, you will see a thin horizontal line over the top of the control.
You can get rid of this line by explicitly set the StatusStrip.BackColor property to any color. In the designer, change the color to anything and set it back to the inherited one (the Form's) and it will disappear. Alternatively, in code, set the property to itself:
private void FormMain_StatusStrip_Setup()
{
this.statusStrip.BackColor = this.statusStrip.BackColor;
//...
}
See Winforms ToolStrip.BackColor returns wrong color for more details about this behavior.
In your case, obviously the BackColor trick has no effect, the line remains as we can see in your image. This could be a result of a custom ToolStripRenderer if you have one assigned to the StatusStrip.Renderer property which uses the default values and ways to render the strips including the borders.
Consider this example:
public class FormMain
{
public FormMain() : base()
{
this.BackColor = Color.Black;
this.statusStrip.Renderer = new MyCustomRenderer();
}
}
public class MyCustomRenderer : ToolStripProfessionalRenderer
{
public MyCustomRenderer() : base(new MyColorTable()) { }
}
public class MyColorTable : ProfessionalColorTable
{
public override Color StatusStripGradientBegin => Color.Black;
public override Color StatusStripGradientEnd => Color.Black;
// ...
}
Here, you need to override the renderer's OnRenderToolStripBorder method to prevent drawing the border of the StatusStrip.
public class MyCustomRenderer : ToolStripProfessionalRenderer
{
public MyCustomRenderer() : base(new MyColorTable()) { }
protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e)
{
if (!(e.ToolStrip is StatusStrip)) base.OnRenderToolStripBorder(e);
}
}
Or maybe to draw the line with a color of your choice:
protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e)
{
if (e.ToolStrip is StatusStrip)
e.Graphics.DrawLine(Pens.Red, 0, 0, e.ToolStrip.Width, 0);
else
base.OnRenderToolStripBorder(e);
}

When I add Application.EnableVisualStyles(); into Main() that problem line disappeared.
namespace test {
class Program {
[STAThread]
static void Main() {
Application.EnableVisualStyles(); // this line added
Application.Run(new FormMain());
}
}
}

Related

Button BorderColor gradient not supporting run time color change?

By using a custom renderer one can create a gradient color effect on the Border of a Button in Xamarin.Forms. Done by editing the BorderColor property in OnElementChanged override method. [Gradient Button credits to #Nico Zhu]
Currently the buttons gradient works on initial start-up. When the border (or StartColor) are changed during run time, the gradient is masked over. See results below. The first is the gradient as shown on load, second shows whats currently selected, and the third is a previously selected button which reverted its border color back to black, but again this still is masking over the initial gradient.
How to support run time changes and maintain the gradient Border on the XF Button?
Xamarin.Forms Gradient Button
using Xamarin.Forms;
namespace XamarinGradientButtonTest
{
public class GradientButton : Button
{
public static readonly BindableProperty StartColorProperty = BindableProperty.Create(
propertyName: "StartColor",
returnType: typeof(Color),
declaringType: typeof(GradientButton),
defaultValue: default(Color));
public Color StartColor
{
get { return (Color)GetValue(StartColorProperty); }
set { SetValue(StartColorProperty, value); }
}
}
}
iOS Renderer
using System;
using CoreAnimation;
using CoreGraphics;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using XamarinGradientButtonTest;
using XamarinGradientButtonTest.iOS;
[assembly: ExportRenderer(typeof(GradientButton), typeof(GradientButtonRenderer))]
namespace XamarinGradientButtonTest.iOS
{
public class GradientButtonRenderer : ButtonRenderer
{
CAGradientLayer gradient;
CAShapeLayer shape;
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
base.OnElementChanged(e);
gradient = new CAGradientLayer();
gradient.Colors = new CGColor[] { ((GradientButton)Element).StartColor.ToCGColor(), Element.BorderColor.ToCGColor() };
shape = new CAShapeLayer();
shape.LineWidth = (nfloat)(Element.BorderWidth);
shape.StrokeColor = UIColor.Black.CGColor;
shape.FillColor = UIColor.Clear.CGColor;
gradient.Mask = shape;
Control.Layer.AddSublayer(gradient);
Control.Layer.BorderColor = UIColor.Clear.CGColor;
}
public override void Draw(CGRect rect)
{
base.Draw(rect);
shape.Path = UIBezierPath.FromRect(rect).CGPath;
gradient.Frame = rect;
}
}
}
XF Button Creation
<local:GradientButton BorderColor="Black" BorderRadius="5" StartColor="White" BorderWidth="8" WidthRequest="50" HeightRequest="44" VerticalOptions="Start" HorizontalOptions="Start"/>
On Click
private void btnClick(object sender, EventArgs e)
{
((GradientButton)sender).BorderColor = Color.Green;
}
On De-Select
BorderColor = Color.Black;
You can set the borderColor in the method OnElementPropertyChanged.Add the following code in GradientButtonRenderer
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if(e.PropertyName=="BorderColor")
{
var color = (Element as GradientButton).BorderColor;
gradient.Colors = new CGColor[] { ((GradientButton)Element).StartColor.ToCGColor(), color.ToCGColor() };
shape.StrokeColor = color.ToCGColor();
shape.FillColor = UIColor.Clear.CGColor;
gradient.Mask = shape;
Control.Layer.AddSublayer(gradient);
Control.Layer.BorderColor = UIColor.Clear.CGColor;
}
}

c# List.Add() unable to add correct values

Program suppose to draw shapes on panel1.
This is code for my main form:
namespace DrawShapes
{
public partial class Form1 : Form
{
List<Shape> myShapeList;
Shape shape;
public Form1()
{
InitializeComponent();
}
public void AddShape(Shape myshape)
{
myShapeList.Add(shape);
}
public List<Shape> MyShapeList
{
get { return myShapeList; }
}
private void Form1_Load(object sender, EventArgs e)
{
myShapeList = new List<Shape>();
shape = new Shape();
}
private void drawMeButton_Click(object sender, EventArgs e)
{
EditShape editShape = new EditShape();
editShape.Shape = shape;
if (editShape.ShowDialog() == DialogResult.OK)
{
this.shape = editShape.Shape;
myShapeList.Add(shape);
panel1.Invalidate();
}
editShape.Dispose();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
int panelWidth = panel1.ClientRectangle.Width;
int panelHeight = panel1.ClientRectangle.Height;
Pen penLine = new Pen(Color.Blue, 1);
Graphics g = e.Graphics;
if (myShapeList != null)
{
foreach (Shape element in myShapeList)
{
label1.Text = element.Width.ToString();
g.DrawRectangle(penLine, element.XCordinates, element.XCordinates, 50, 50);
}
}
}
}
}
and here is code for my edit shape dialog box
namespace DrawShapes
{
public partial class EditShape : Form
{
Shape shape = null;
public EditShape()
{
InitializeComponent();
}
public Shape Shape
{
get { return shape; }
set { shape = value; }
}
private void button1_Click(object sender, EventArgs e)
{
shape.Width = 50;
shape.Height = 50;
shape.XCordinates = int.Parse(textBox1.Text);
shape.YCordinates = int.Parse(textBox2.Text);
shape.Type = 0;
DialogResult = DialogResult.OK;
}
}
}
I am having problem assigning shape object(from Edit Shape form) to myShapeList, all properties are set to 0 for some reason. Please help.
Perhaps the problem is your AddShape method. You seem to be adding shape each time instead of the shape that's getting passed into the method (myshape).
What happens if you do this instead?
public void AddShape(Shape myshape)
{
myShapeList.Add(myshape); // myshapeinstead of shape
}
It seems that you're not actually adding your shape to your shapelist. You're taking in myShape and then trying to add in shape. This should come up as an intellisense error.
public void AddShape(Shape myshape)
{
myShapeList.Add(shape);
}
EDIT: Nevermind, it wouldn't come up as an error because you have a member variable named shape. You're getting zero for everything because it's calling the default constructor for shape.
The big problem is in your call to the edit form. You are adding to the list the same object reference. So when you modify the reference inside the edit form you change all the elements added to the list to the inputs set in the latest call
Change your code to
private void drawMeButton_Click(object sender, EventArgs e)
{
using(EditShape editShape = new EditShape())
{
// Here, create a new instance of a Shape and edit it....
editShape.Shape = new Shape();
if (editShape.ShowDialog() == DialogResult.OK)
{
// Add the new instance to the list, not the same instance
// declared globally. (and, at this point, useless)
myShapeList.Add(editShape.Shape);
panel1.Invalidate();
}
// The using blocks makes this call superflous
// editShape.Dispose();
}
}
Then it is not clear when you call the method AddShape(Shape myshape) but it is clear that you have typo in that method
I have found my mistake.I Created new event handler with wrong parameters. Therefore information that suppose to be passed by my dialog OK button was never correctly assigned. Silly mistake. Thanks guys.

How to get a C# Custom TextBox to change cursor location on mouse click

I have a custom textbox, which is just a standard textbox with a couple additional small features, and it all works as expected. The problem I am having is that clicking in the field to change the cursor location does not actually change the location of the cursor, the cursor just stays at the beginning of the field.
Below is the code I am working with, I am hoping someone will be able to tell me what I am missing:
using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Test.UI.Controls
{
public partial class TestTextBox : TextBox
{
private Color normalForegroundColor = Color.Gray;
private Color textChangedForegroundColor = Color.Red;
private string startingText = string.Empty;
[Description("TextBox border color when text is changed"), Category("Appearance")]
public Color TextChangedColor
{
get { return textChangedForegroundColor; }
set { textChangedForegroundColor = value; }
}
[Description("Set starting text of textbox, as well as the Text property"), Category("Appearance")]
public String StartingText
{
get { return startingText; }
set
{
startingText = value;
this.Text = startingText;
}
}
public TestTextBox()
{
InitializeComponent();
normalForegroundColor = this.ForeColor;
}
protected override void OnTextChanged(EventArgs e)
{
base.OnTextChanged(e);
this.ForeColor = this.Text == startingText ? normalForegroundColor : textChangedForegroundColor;
}
}
}
Below is a screen grab of what the custom textbox looks like with data in it:

How can I remove a CheckBox's borders?

I'd like to create a CheckBox without borders. It should still display the checkmark when checked.
using System;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.Linq;
using System.Text;
namespace WindowsFormsApplication1
{
public class RoundButton : Button
{
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
GraphicsPath grPath = new GraphicsPath();
grPath.AddEllipse(0, 0, ClientSize.Width, ClientSize.Height);
this.Region = new System.Drawing.Region(grPath);
base.OnPaint(e);
}
private void InitializeComponent()
{
this.SuspendLayout();
this.ResumeLayout(false);
}
}
}
this is a class that generate a customized round button, can be good starter for you to make your own customCheckbox by doing similarly
The verified answer on this question states:
You cannot remove just the border because the check box is drawn by windows and it's pretty much all or nothing.
This is because the System.Windows.CheckBox is a native control.
A workaround to this would be drawing you own CustomCheckBox, with no visible borders.
Hope this helps.
Following AndreiV advice, I created a CustomControl which inherited from Label. Next I override the OnPaint and OnClick events to make it look and behave like a CheckBox. In order to display the check box "checked image" I used a bit of paint for cropping it to what I needed.
Below is the full code:
public partial class FlatCheckBox : Label
{
public bool Checked { get; set; }
public FlatCheckBox()
{
InitializeComponent();
Checked = false;
}
protected override void OnClick(EventArgs e)
{
Checked = !Checked;
Invalidate();
}
protected override void OnPaint(PaintEventArgs pevent)
{
if (!DesignMode)
{
pevent.Graphics.Clear(Color.White);
var bigRectangle = new Rectangle(pevent.ClipRectangle.X, pevent.ClipRectangle.Y,
pevent.ClipRectangle.Width, pevent.ClipRectangle.Height);
var smallRectangle = new Rectangle(pevent.ClipRectangle.X + 1, pevent.ClipRectangle.Y + 1,
pevent.ClipRectangle.Width - 2, pevent.ClipRectangle.Height - 2);
var b = new SolidBrush(UllinkColors.NEWBLUE);
var b2 = new SolidBrush(Color.White);
pevent.Graphics.FillRectangle(b, bigRectangle);
pevent.Graphics.FillRectangle(b2, smallRectangle);
if (Checked)
{
pevent.Graphics.DrawImage(Resources.flatCheckedBox, new Point(3, 3));
}
}
}
}

Display specific properties in the Property grid

When we press the btnSettings, all the user controls properties will be displayed in Property grid. I want display specific properties (only TemperatureValue and TemperatureUnit), is possible? User control code as follows:
using System;
using System.Windows.Forms;
namespace Temperature
{
public partial class temperatureUc : UserControl
{
public enum temperatureUnit
{
Celsius, // default
Delisle, // °De = (100 − °C) * 3⁄2
Fahrenheit, // °F = °C * 9⁄5 + 32
Kelvin, // °K = °C + 273.15
Newton, // °N = °C * 33⁄100
Rankine, // °R = (°C + 273.15) * 9⁄5
Réaumur, // °Ré = °C * 4⁄5
Rømer // °Rø = °C * 21⁄40 + 7.5
}
public temperatureUc()
{
InitializeComponent();
this.cboTemperatureUnit.DataSource = Enum.GetValues(typeof(temperatureUnit));
}
#region "Event"
public delegate void SettingsStateEventHandler(object sender, EventArgs e);
public event SettingsStateEventHandler settingsStateChanged;
private void OnSettingsChanged(object sender, EventArgs e)
{
if (this.settingsStateChanged != null)
this.settingsStateChanged(sender, e);
}
#endregion
#region "Properties"
private Single _TemperatureValue;
public Single TemperatureValue
{
get
{
return this._TemperatureValue;
}
set
{
if (value.GetType() == typeof(Single))
{
_TemperatureValue = value;
this.txtTemperatureValue.Text = _TemperatureValue.ToString();
}
}
}
private temperatureUnit _TemperatureUnit;
public temperatureUnit TemperatureUnit
{
get
{
return this._TemperatureUnit;
}
set
{
if (value.GetType() == typeof(temperatureUnit))
{
_TemperatureUnit = value;
this.cboTemperatureUnit.Text = _TemperatureUnit.ToString();
}
}
}
#endregion
private void btnSettings_Click(object sender, EventArgs e)
{
this.OnSettingsChanged(sender, e);
}
}
}
User control above code will be called from code bellow:
using System;
using System.Windows.Forms;
using Temperature;
using System.Diagnostics;
using System.Drawing;
namespace TemperatureImplements
{
public partial class Form1 : Form
{
private PropertyGrid pGrid = new PropertyGrid();
public Form1()
{
InitializeComponent();
this.temperatureUc1.settingsStateChanged += new temperatureUc.SettingsStateEventHandler(temperatureUc1_settingsStateChanged);
}
void temperatureUc1_settingsStateChanged(object sender, EventArgs e)
{
pGrid.Size = new Size(300, 500);
pGrid.Location = new Point(300,10);
pGrid.SelectedObject = temperatureUc1;
this.Controls.Add(pGrid);
}
}
}
Picture as follows:
There is a way. This article has a section called "Customizing the PropertyGrid Control" that explains how to do it http://msdn.microsoft.com/en-us/library/aa302326.aspx#usingpropgrid_topic5
Basically you just want to define the AppSettings class to only include TemperatureUnit andTemeratureValue`.
AppSettings appset = new AppSettings();
MyPropertyGrid.SelectedObject = appset;
Define AppSettings as follows;
[DefaultPropertyAttribute("SaveOnClose")]
public class AppSettings{
private bool saveOnClose = true;
private string tempUnit;
private int tempValue;
[CategoryAttribute("Global Settings"),
ReadOnlyAttribute(false),
DefaultValueAttribute("Celsius")]
public string TemperatureUnit
{
get { return tempUnit; }
set { tempUnit = value; }
}
[CategoryAttribute("Global Settings"),
ReadOnlyAttribute(false),
DefaultValueAttribute(0)]
public string TemperatureValue
{
get { return tempValue; }
set { tempValue = value; }
}
}
By the way, I'm changing the category from Misc to Global Settings, don't know if that's what you want but it makes sense when they're the only options. You may have to explicitly declare the other attributes this BrowsableAttribute(false) so they're not displayed but I don't think it's necessary.
There might be a way to hide those properties but I think that's the wrong way to go about it.
Instead of passing the user control itself you should create a model with TemperatureUnit and TemperatureValue. Move your defined events to this model.
Then you need to extend a user control which you pass the model to and listens for these events.
Finally set pGrid.SelectedObject to your model and you'll be good to go.

Categories