I want to change the background color of a custom control that I found on the internet.
The code looks like this:
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
namespace BetterNotepad
{
public class TabControlZ : System.Windows.Forms.TabControl
{
private Color nonactive_color1 = Color.LightGreen;
private Color nonactive_color2 = Color.DarkBlue;
private Color backcolor = Color.WhiteSmoke;
private Color active_color1 = Color.FromArgb(255, 210, 250, 220);
private Color active_color2 = Color.FromArgb(255, 140, 160, 200);
public Color forecolor = Color.Navy;
private int color1Transparent = 150;
private int color2Transparent = 150;
private System.ComponentModel.IContainer components;
private int angle = 90;
public Color ActiveTabStartColor
{
get { return active_color1; }
set { active_color1 = value; Invalidate(); }
}
public Color ActiveTabEndColor
{
get { return active_color2; }
set { active_color2 = value; Invalidate(); }
}
public Color NonActiveTabStartColor
{
get { return nonactive_color1; }
set { nonactive_color1 = value; Invalidate(); }
}
public Color NonActiveTabEndColor
{
get { return nonactive_color2; }
set { nonactive_color2 = value; Invalidate(); }
}
public Color BackroudColor
{
get { return backcolor; }
set { backcolor = value; Invalidate(); }
}
public int Transparent1
{
get { return color1Transparent; }
set
{
color1Transparent = value;
if (color1Transparent > 255)
{
color1Transparent = 255;
Invalidate();
}
else
Invalidate();
}
}
public int Transparent2
{
get { return color2Transparent; }
set
{
color2Transparent = value;
if (color2Transparent > 255)
{
color2Transparent = 255;
Invalidate();
}
else
Invalidate();
}
}
public int GradientAngle
{
get { return angle; }
set { angle = value; Invalidate(); }
}
public Color TextColor
{
get { return forecolor; }
set { forecolor = value; Invalidate(); }
}
public TabControlZ()
{
this.DrawMode = TabDrawMode.OwnerDrawFixed;
this.Padding = new System.Drawing.Point(30, 4);
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
}
protected override void OnDrawItem(DrawItemEventArgs e)
{
base.OnDrawItem(e);
Rectangle rc = GetTabRect(e.Index);
Rectangle rc2 = GetTabRect(e.Index);
if (this.SelectedTab == this.TabPages[e.Index])
{
Color c1 = Color.FromArgb(color1Transparent, active_color1);
Color c2 = Color.FromArgb(color2Transparent, active_color2);
using (LinearGradientBrush br = new LinearGradientBrush(rc, c1, c2, angle))
{
e.Graphics.FillRectangle(br, rc);
}
}
else
{
Color c1 = Color.FromArgb(color1Transparent, nonactive_color1);
Color c2 = Color.FromArgb(color2Transparent, nonactive_color2);
using (LinearGradientBrush br = new LinearGradientBrush(rc, c1, c2, angle))
{
e.Graphics.FillRectangle(br, rc);
}
}
this.TabPages[e.Index].BorderStyle = BorderStyle.FixedSingle;
this.TabPages[e.Index].ForeColor = SystemColors.ControlText;
Rectangle paddedBounds = e.Bounds;
paddedBounds.Inflate(-12, -4);
e.Graphics.DrawString(this.TabPages[e.Index].Text, this.Font, new SolidBrush(forecolor), paddedBounds);
}
private void InitializeComponent()
{
this.SuspendLayout();
this.ResumeLayout(false);
}
}
}
But the background color is white:
the withe part is the tab control and the black part is a richtextbox.
I expected the background color to change but it did not happen. I have tried to add
base.BackColor = Color.Black;
But it does not work.
I made a Custom Control with the functions of a Button.
The problem with this controls is that when you hover over it, the color of the button changes: when this action is repeated quickly, it glitches out.
To make it more clear, I recorded a video.
Update 09.07.2020;
I updated the code, perhaps this is because I do not add the image correctly, although judging by the appearance, the original, everything seems to be correct, the image works, but what happens next, you have already seen in the video.
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace Test_Project.SupportClass
{
[DesignerCategory("Code")]
public class button_check : Control
{
private int m_BorderSize = 2;
private int m_ButtonRoundRadius = 15;
private bool IsHighlighted = false;
private bool IsPressed = false;
private Image _image;
private ImageLayout LautsCallBack { get; set; }
public button_check()
{
SetStyle(ControlStyles.Opaque |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.ResizeRedraw |
ControlStyles.UserPaint, true);
// To be explicit...
SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
this.DoubleBuffered = false;
InitializeComponent();
}
private void InitializeComponent()
{
Size = new Size(100, 40);
BackColor = Color.Tomato;
BackColor2 = Color.Tomato;
ButtonBorderColor = Color.Black;
ButtonHighlightColor = Color.Orange;
ButtonHighlightColor2 = Color.OrangeRed;
ButtonHighlightForeColor = Color.Black;
ButtonPressedColor = Color.Red;
ButtonPressedColor2 = Color.Maroon;
ButtonPressedForeColor = Color.White;
}
public ImageLayout LayoutImage
{
get
{
return LautsCallBack;
}
set
{
LautsCallBack = value;
RecreateHandle();
}
}
public Image ImageButtom
{
get
{
return _image;
}
set
{
_image = value;
RecreateHandle();
}
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x00000020; // WS_EX_TRANSPARENT
return cp;
}
}
// Invalidate(rect) in Design-Mode to refresh the view
public int BorderSize
{
get => m_BorderSize;
set
{
m_BorderSize = Math.Max(Math.Min(value, 6), 1);
RepaintControl();
}
}
// Set Max = 44, Min = 1 to avoid quirks and exceptions
public int ButtonRoundRadius
{
get => m_ButtonRoundRadius;
set
{
m_ButtonRoundRadius = Math.Max(Math.Min(value, 44), 1);
RepaintControl();
}
}
public override string Text
{
get => base.Text;
set
{
base.Text = value;
RepaintControl();
}
}
// You should Invalidate the Parent also when these change
public Color BorderColor { get; set; } = Color.Tomato;
public Color BackColor2 { get; set; } = Color.Tomato;
public Color ButtonBorderColor { get; set; }
public Color ButtonHighlightColor { get; set; }
public Color ButtonHighlightColor2 { get; set; }
public Color ButtonHighlightForeColor { get; set; }
public Color ButtonPressedColor { get; set; }
public Color ButtonPressedColor2 { get; set; }
public Color ButtonPressedForeColor { get; set; }
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
var foreColor = IsPressed ? ButtonPressedForeColor : IsHighlighted ? ButtonHighlightForeColor : ForeColor;
var backColor = IsPressed ? ButtonPressedColor : IsHighlighted ? ButtonHighlightColor : BackColor;
var backColor2 = IsPressed ? ButtonPressedColor2 : IsHighlighted ? ButtonHighlightColor2 : BackColor2;
var rect = Path.GetBounds();
using (var pen = new Pen(ButtonBorderColor, m_BorderSize))
using (var pathBrush = new LinearGradientBrush(rect, backColor, backColor2, LinearGradientMode.Vertical))
using (var textBrush = new SolidBrush(foreColor))
using (var sf = new StringFormat())
{
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
e.Graphics.FillPath(pathBrush, Path);
if (m_BorderSize > 0) e.Graphics.DrawPath(pen, Path);
if (_image != null)
{
switch (LayoutImage)
{
case ImageLayout.Stretch:
e.Graphics.DrawImage(_image, this.ClientRectangle);
break;
case ImageLayout.Center:
int left = (this.ClientSize.Width - _image.Width) / 2;
int top = (this.ClientSize.Height - _image.Height) / 2;
e.Graphics.DrawImage(_image, left, top);
break;
case ImageLayout.Tile:
using (var texture = new TextureBrush(_image))
{
e.Graphics.FillRectangle(texture, this.ClientRectangle);
}
break;
case ImageLayout.Zoom:
double xr = (double)this.ClientSize.Width / _image.Width;
double yr = (double)this.ClientSize.Height / _image.Height;
if (xr > yr)
{
rect.Width = (int)(_image.Width * yr);
rect.X = (this.ClientSize.Width - rect.Width) / 2;
}
else
{
rect.Height = (int)(_image.Height * xr);
rect.Y = (this.ClientSize.Height - rect.Height) / 2;
}
e.Graphics.DrawImage(_image, rect);
break;
}
}
rect.Inflate(-4, -4);
e.Graphics.DrawString(Text, Font, textBrush, rect, sf);
}
}
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
IsHighlighted = true;
RepaintControl();
}
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
IsHighlighted = false;
IsPressed = false;
RepaintControl();
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
IsPressed = true;
RepaintControl();
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
IsPressed = false;
RepaintControl();
}
private void RepaintControl()
{
Parent?.Invalidate(this.Bounds, true);
Invalidate();
}
private GraphicsPath Path
{
get
{
var rect = ClientRectangle;
int scaleOnBorder = -((m_BorderSize / 2) + 2);
rect.Inflate(scaleOnBorder, scaleOnBorder);
return GetRoundedRectangle(rect, m_ButtonRoundRadius);
}
}
private GraphicsPath GetRoundedRectangle(Rectangle rect, int d)
{
var gp = new GraphicsPath();
gp.StartFigure();
gp.AddArc(rect.X, rect.Y, d, d, 180, 90);
gp.AddArc(rect.X + rect.Width - d, rect.Y, d, d, 270, 90);
gp.AddArc(rect.X + rect.Width - d, rect.Y + rect.Height - d, d, d, 0, 90);
gp.AddArc(rect.X, rect.Y + rect.Height - d, d, d, 90, 90);
gp.CloseFigure();
return gp;
}
}
}
All right, try your Button with these modifications:
► SetStyle(ControlStyles.Opaque, true) is set. Combined with WS_EX_TRANSPARENT, you have a fully transparent Control that supports TransparentColor. No need to also set ControlStyles.SupportsTransparentBackColor, it's understood.
► Double buffering is explicitly disable, since we're painting the Control ourselves when required (ControlStyles.AllPaintingInWmPaint, ControlStyles.UserPaint and ControlStyles.ResizeRedraw are all set).
► Moved the invalidating functions to the RepaintControl() method, including invalidating the parent Control, if available, when in design-mode. At run-time, Invalidate() is enough.
► Recalculated the GraphicsPath bounds when the BorderSize is changed, so the border is always painted inside the Control's bounds (to preserve anti-aliasing, which requires at least one pixel to render correctly. When too close to the Control's bounds, the rendering is incomplete).
► base.OnPaint(e) is still called, but you only need it if you want to allow User customization of the Control. Otherwise, you can remove it (or place it after your code, at the bottom of the OnPaint method).
► Added, as example, Min/Max checkes on some properties:
The BorderSize is limited in the range (0, 6) with Math.Max(Math.Min(value, 6), 0)
The ButtonRoundRadius is limited to range (1, 44) with Math.Max(Math.Min(value, 44), 1): the GraphicsPath cannot add arcs with a null angle and, above 45, it'll generate re-entrant curves.
I don't see any flickering at run-time.
Note that this is tested with .Net Framework 4.8
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
[DesignerCategory("Code")]
public class l1_Button : Control
{
private int m_BorderSize = 2;
private int m_ButtonRoundRadius = 15;
private bool IsHighlighted = false;
private bool IsPressed = false;
public l1_Button()
{
SetStyle(ControlStyles.Opaque |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.ResizeRedraw |
ControlStyles.UserPaint, true);
// To be explicit...
SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
this.DoubleBuffered = false;
InitializeComponent();
}
private void InitializeComponent()
{
Size = new Size(100, 40);
BackColor = Color.Tomato;
BackColor2 = Color.Tomato;
ButtonBorderColor = Color.Black;
ButtonHighlightColor = Color.Orange;
ButtonHighlightColor2 = Color.OrangeRed;
ButtonHighlightForeColor = Color.Black;
ButtonPressedColor = Color.Red;
ButtonPressedColor2 = Color.Maroon;
ButtonPressedForeColor = Color.White;
}
protected override CreateParams CreateParams {
get {
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x00000020; // WS_EX_TRANSPARENT
return cp;
}
}
// Invalidate(rect) in Design-Mode to refresh the view
public int BorderSize {
get => m_BorderSize;
set {
m_BorderSize = Math.Max(Math.Min(value, 6), 1);
RepaintControl();
}
}
// Set Max = 44, Min = 1 to avoid quirks and exceptions
public int ButtonRoundRadius {
get => m_ButtonRoundRadius;
set {
m_ButtonRoundRadius = Math.Max(Math.Min(value, 44), 1);
RepaintControl();
}
}
public override string Text {
get => base.Text;
set {
base.Text = value;
RepaintControl();
}
}
// You should Invalidate the Parent also when these change
public Color BorderColor { get; set; } = Color.Tomato;
public Color BackColor2 { get; set; } = Color.Tomato;
public Color ButtonBorderColor { get; set; }
public Color ButtonHighlightColor { get; set; }
public Color ButtonHighlightColor2 { get; set; }
public Color ButtonHighlightForeColor { get; set; }
public Color ButtonPressedColor { get; set; }
public Color ButtonPressedColor2 { get; set; }
public Color ButtonPressedForeColor { get; set; }
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
var foreColor = IsPressed ? ButtonPressedForeColor : IsHighlighted ? ButtonHighlightForeColor : ForeColor;
var backColor = IsPressed ? ButtonPressedColor : IsHighlighted ? ButtonHighlightColor : BackColor;
var backColor2 = IsPressed ? ButtonPressedColor2 : IsHighlighted ? ButtonHighlightColor2 : BackColor2;
var rect = Path.GetBounds();
using (var pen = new Pen(ButtonBorderColor, m_BorderSize))
using (var pathBrush = new LinearGradientBrush(rect, backColor, backColor2, LinearGradientMode.Vertical))
using (var textBrush = new SolidBrush(foreColor))
using (var sf = new StringFormat()) {
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
e.Graphics.FillPath(pathBrush, Path);
if (m_BorderSize > 0) e.Graphics.DrawPath(pen, Path);
rect.Inflate(-4, -4);
e.Graphics.DrawString(Text, Font, textBrush, rect, sf);
}
}
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
IsHighlighted = true;
RepaintControl();
}
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
IsHighlighted = false;
IsPressed = false;
RepaintControl();
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
IsPressed = true;
RepaintControl();
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
IsPressed = false;
RepaintControl();
}
private void RepaintControl() {
Parent?.Invalidate(this.Bounds, true);
Invalidate();
}
private GraphicsPath Path {
get {
var rect = ClientRectangle;
int scaleOnBorder = -((m_BorderSize / 2) + 2);
rect.Inflate(scaleOnBorder, scaleOnBorder);
return GetRoundedRectangle(rect, m_ButtonRoundRadius);
}
}
private GraphicsPath GetRoundedRectangle(Rectangle rect, int d)
{
var gp = new GraphicsPath();
gp.StartFigure();
gp.AddArc(rect.X, rect.Y, d, d, 180, 90);
gp.AddArc(rect.X + rect.Width - d, rect.Y, d, d, 270, 90);
gp.AddArc(rect.X + rect.Width - d, rect.Y + rect.Height - d, d, d, 0, 90);
gp.AddArc(rect.X, rect.Y + rect.Height - d, d, d, 90, 90);
gp.CloseFigure();
return gp;
}
}
I want to design above screen in windows forms. When I am tried to use checkbox control the size of the box is not increasing.
I tried below code but checkbox color and bored color is not changing.
using System;
using System.Drawing;
using System.Windows.Forms;
class MyCheckBox : CheckBox {
public MyCheckBox() {
this.TextAlign = ContentAlignment.MiddleRight;
}
public override bool AutoSize {
get { return base.AutoSize; }
set { base.AutoSize = false; }
}
protected override void OnPaint(PaintEventArgs e) {
base.OnPaint(e);
int h = this.ClientSize.Height - 2;
Rectangle rc = new Rectangle(new Point(0, 1), new Size(h, h));
ControlPaint.DrawCheckBox(e.Graphics, rc,
this.Checked ? ButtonState.Checked : ButtonState.Normal);
}
}
RadioButton also tried but I don't know how to apply colors and highlight the text.
using System;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsForms
{
public class BiggerCheckBox : CheckBox
{
#region variables
private int _boxsize = 14;
private int _boxlocatx = 0;
private int _boxlocaty = 0;
private int _textX = 16;
private int _textY = 1;
private Color _boxBackColor = Color.Transparent;
private Color _tickColor = Color.Black;
private float _tickSize = 11f;
private Color _boxColor = Color.Black;
private float _tickLeftPosition = 0f;
private float _tickTopPosition = 0f;
#endregion
#region Properties
public int TextLocationX
{
get { return _textX; }
set { _textX = value; Invalidate(); }
}
public int TextLocationY
{
get { return _textY; }
set { _textY = value; Invalidate(); }
}
public int BoxSize
{
get { return _boxsize; }
set { _boxsize = value; Invalidate(); }
}
public int BoxLocationX
{
get { return _boxlocatx; }
set { _boxlocatx = value; Invalidate(); }
}
public int BoxLocationY
{
get { return _boxlocaty; }
set { _boxlocaty = value; Invalidate(); }
}
public Color BoxBackColor
{
get { return _boxBackColor; }
set { _boxBackColor = value; Invalidate(); }
}
public Color TickColor
{
get { return _tickColor; }
set { _tickColor = value; Invalidate(); }
}
public float TickSize
{
get { return _tickSize; }
set { _tickSize = value; Invalidate(); }
}
public Color BoxColor
{
get { return _boxColor; }
set { _boxColor = value; Invalidate(); }
}
public float TickLeftPosition
{
get { return _tickLeftPosition; }
set { _tickLeftPosition = value; Invalidate(); }
}
public float TickTopPosition
{
get { return _tickTopPosition; }
set { _tickTopPosition = value; Invalidate(); }
}
#endregion
#region Constrctors
public BiggerCheckBox()
{
Appearance = Appearance.Button;
FlatStyle = FlatStyle.Flat;
TextAlign = ContentAlignment.MiddleRight;
FlatAppearance.BorderSize = 0;
AutoSize = false;
}
#endregion
#region Methods
protected override void OnPaint(PaintEventArgs pevent)
{
try
{
base.OnPaint(pevent);
pevent.Graphics.Clear(BackColor);
//checkbox text - using draw string method with specified location
using (SolidBrush brushText = new SolidBrush(ForeColor))
{
pevent.Graphics.DrawString(Text, Font, brushText, _textX, _textY);
}
//checkbox box - using rectangle for checkbox box
Rectangle _rectangleBox = new Rectangle(_boxlocatx, _boxlocaty, _boxsize, _boxsize);
//checkbox box - checckbox box back color and border color
using (SolidBrush brushBackColor = new SolidBrush(_boxBackColor))
{
pevent.Graphics.FillRectangle(brushBackColor, _rectangleBox);
}
using (Pen penBoxColor = new Pen(_boxColor))
{
pevent.Graphics.DrawRectangle(penBoxColor, _rectangleBox);
}
//checkbox box - check and uncheck
if (Checked)
{
using (SolidBrush brush = new SolidBrush(_tickColor))
{
using (Font wing = new Font("Wingdings", _tickSize))
{
pevent.Graphics.DrawString("ü", wing, brush, _tickLeftPosition, _tickTopPosition);
}
}
}
pevent.Dispose();
}
catch (Exception ex)
{
}
}
#endregion
}
}
I created a custom Panel which consists of a Panel and two Scrollbars.
When i try to add Controls on it add design time, it won't Display them, but at runtime i am able to see them.
This is what my current Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms.Design;
namespace MaterialWinforms.Controls
{
[Designer(typeof(ParentControlDesigner))]
public class MaterialPanel : Control, IMaterialControl
{
[Browsable(false)]
public int Depth { get; set; }
[Browsable(false)]
public MaterialSkinManager SkinManager { get { return MaterialSkinManager.Instance; } }
[Browsable(false)]
public MouseState MouseState { get; set; }
public Boolean AutoScroll
{
get
{
return MainPanel.AutoScroll;
}
set
{
MainPanel.AutoScroll = value;
VerticalScrollbar.Visible = MainPanel.VerticalScroll.Visible;
VerticalScrollbarAdded = VerticalScrollbar.Visible;
HorizontalScrollbar.Visible = MainPanel.HorizontalScroll.Visible;
HorizontalScrollbarAdded = HorizontalScrollbar.Visible;
}
}
public new bool AutoSize
{
get
{
return MainPanel.AutoSize;
}
set
{
MainPanel.AutoSize = value;
base.AutoSize = value;
}
}
private MaterialScrollBar VerticalScrollbar, HorizontalScrollbar;
private Boolean VerticalScrollbarAdded, HorizontalScrollbarAdded;
private MaterialDisplayingPanel MainPanel;
private bool ignoreResize = true;
private bool ignoreMainPanelResize = false;
public override Color BackColor { get { return SkinManager.GetCardsColor(); } }
public new ControlCollection Controls
{
get
{
return MainPanel.Controls;
}
}
public MaterialPanel()
{
DoubleBuffered = true;
VerticalScrollbar = new MaterialScrollBar(MaterialScrollOrientation.Vertical);
VerticalScrollbar.Scroll += Scrolled;
VerticalScrollbar.Visible = false;
VerticalScrollbarAdded = false;
HorizontalScrollbar = new MaterialScrollBar(MaterialScrollOrientation.Horizontal);
HorizontalScrollbar.Scroll += Scrolled;
HorizontalScrollbar.Visible = false;
HorizontalScrollbarAdded = false;
MainPanel = new MaterialDisplayingPanel();
MainPanel.Resize += MainPanel_Resize;
MainPanel.Location = new Point(0, 0);
Size = new Size(90, 90);
base.Controls.Add(MainPanel);
base.Controls.Add(VerticalScrollbar);
base.Controls.Add(HorizontalScrollbar);
MainPanel.ControlAdded += MaterialPanel_ControlsChanged;
MainPanel.ControlRemoved += MaterialPanel_ControlsChanged;
MainPanel.onScrollBarChanged += MainPanel_onScrollBarChanged;
AutoScroll = true;
ignoreResize = false;
}
protected override void OnControlAdded(ControlEventArgs e)
{
base.OnControlAdded(e);
VerticalScrollbar.BringToFront();
HorizontalScrollbar.BringToFront();
MainPanel.BringToFront();
}
void MainPanel_onScrollBarChanged(Orientation pScrollOrientation, bool pVisible)
{
UpdateScrollbars();
}
void Scrolled(object sender, ScrollEventArgs e)
{
MainPanel.AutoScrollPosition = new Point(HorizontalScrollbar.Value, VerticalScrollbar.Value);
}
void MaterialPanel_ControlsChanged(object sender, ControlEventArgs e)
{
UpdateScrollbars();
MainPanel.BringToFront();
VerticalScrollbar.BringToFront();
HorizontalScrollbar.BringToFront();
}
protected override void OnLayout(LayoutEventArgs levent)
{
base.OnLayout(levent);
MainPanel.BringToFront();
VerticalScrollbar.BringToFront();
HorizontalScrollbar.BringToFront();
}
void MainPanel_Resize(object sender, EventArgs e)
{
if (!ignoreMainPanelResize)
UpdateScrollbars();
else
ignoreMainPanelResize = false;
}
protected override void OnResize(EventArgs eventargs)
{
VerticalScrollbar.Location = new Point(Width - VerticalScrollbar.Width, 0);
VerticalScrollbar.Size = new Size(VerticalScrollbar.Width, Height - HorizontalScrollbar.Height);
VerticalScrollbar.Anchor = ((AnchorStyles)AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right);
HorizontalScrollbar.Location = new Point(0, Height - HorizontalScrollbar.Height);
HorizontalScrollbar.Size = new Size(Width - VerticalScrollbar.Width, HorizontalScrollbar.Height);
HorizontalScrollbar.Anchor = ((AnchorStyles)AnchorStyles.Left | AnchorStyles.Bottom | AnchorStyles.Right);
base.OnResize(eventargs);
UpdateScrollbars();
}
private void UpdateScrollbars()
{
if(ignoreResize)
{
return;
}
VerticalScrollbar.Minimum = MainPanel.VerticalScroll.Minimum;
VerticalScrollbar.Maximum = MainPanel.VerticalScroll.Maximum;
VerticalScrollbar.LargeChange = MainPanel.VerticalScroll.LargeChange;
VerticalScrollbar.SmallChange = MainPanel.VerticalScroll.SmallChange;
HorizontalScrollbar.Minimum = MainPanel.HorizontalScroll.Minimum;
HorizontalScrollbar.Maximum = MainPanel.HorizontalScroll.Maximum;
HorizontalScrollbar.LargeChange = MainPanel.HorizontalScroll.LargeChange;
HorizontalScrollbar.SmallChange = MainPanel.HorizontalScroll.SmallChange;
if (MainPanel.VerticalScroll.Visible && !VerticalScrollbarAdded)
{
VerticalScrollbarAdded = true;
VerticalScrollbar.Visible = true;
}
else if (!MainPanel.VerticalScroll.Visible && VerticalScrollbarAdded)
{
VerticalScrollbarAdded = false;
VerticalScrollbar.Visible = false;
}
if (MainPanel.HorizontalScroll.Visible && !HorizontalScrollbarAdded)
{
HorizontalScrollbarAdded = true;
HorizontalScrollbar.Visible = true;
}
else if (!MainPanel.HorizontalScroll.Visible && HorizontalScrollbarAdded)
{
HorizontalScrollbarAdded = false;
HorizontalScrollbar.Visible = false;
}
ignoreMainPanelResize = true;
Size MainPanelSize = new Size(Width - (VerticalScrollbarAdded ? VerticalScrollbar.Width : 0), Height - (HorizontalScrollbarAdded ? HorizontalScrollbar.Height : 0));
MainPanel.IgnoreResizing = true;
ignoreMainPanelResize = true;
MainPanel.Size = new Size(Width - (VerticalScrollbarAdded ? VerticalScrollbar.Width : 0), Height - (HorizontalScrollbarAdded ? HorizontalScrollbar.Height : 0));
MainPanel.IgnoreResizing = false;
ignoreMainPanelResize = false;
}
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.Clear(BackColor);
}
}
internal class MaterialDisplayingPanel : Panel, IMaterialControl
{
[Browsable(false)]
public int Depth { get; set; }
[Browsable(false)]
public MaterialSkinManager SkinManager { get { return MaterialSkinManager.Instance; } }
[Browsable(false)]
public MouseState MouseState { get; set; }
public override Color BackColor { get { return SkinManager.GetApplicationBackgroundColor(); } }
public delegate void ScrollbarChanged(Orientation pScrollOrientation, Boolean pVisible);
public bool IgnoreResizing = false;
public event ScrollbarChanged onScrollBarChanged;
public MaterialDisplayingPanel()
{
DoubleBuffered = true;
Padding = new Padding(3, 3, 3, 3);
}
protected override void OnLayout(LayoutEventArgs e)
{
base.OnLayout(e);
foreach (Control objControl in Controls)
{
objControl.BringToFront();
}
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool ShowScrollBar(IntPtr hWnd, int wBar, bool bShow);
private enum ScrollBarDirection
{
SB_HORZ = 0,
SB_VERT = 1,
SB_CTL = 2,
SB_BOTH = 3
}
protected override void OnResize(EventArgs eventargs)
{
base.OnResize(eventargs);
if (onScrollBarChanged != null)
{
onScrollBarChanged(Orientation.Horizontal, HorizontalScroll.Visible);
onScrollBarChanged(Orientation.Vertical, VerticalScroll.Visible);
}
}
protected override void WndProc(ref System.Windows.Forms.Message m)
{
if (onScrollBarChanged != null && ! IgnoreResizing)
{
onScrollBarChanged(Orientation.Horizontal, HorizontalScroll.Visible);
onScrollBarChanged(Orientation.Vertical, VerticalScroll.Visible);
}
ShowScrollBar(this.Handle, (int)ScrollBarDirection.SB_HORZ, false);
ShowScrollBar(this.Handle, (int)ScrollBarDirection.SB_VERT, false);
base.WndProc(ref m);
}
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.Clear(BackColor);
foreach (Control objChild in Controls)
{
if (typeof(IShadowedMaterialControl).IsAssignableFrom(objChild.GetType()))
{
IShadowedMaterialControl objCurrent = (IShadowedMaterialControl)objChild;
DrawHelper.drawShadow(e.Graphics, objCurrent.ShadowBorder, objCurrent.Elevation, SkinManager.GetApplicationBackgroundColor());
}
}
}
}
}
What am i doing wrong or missing ?
i am trying to serialize a field of my class. Withou it serialization is fine, with it a get SerializationException.
Field is : private readonly ObservableCollection<CellVM> Values;
Exception is
Type System.ComponentModel.PropertyChangedEventManager in assembly WindowsBase, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 is not marked as serializable.
I am targeting Framework 3.5.
I found some suggestions, that it could be problem with serialization of observalble collections, but that should be fixed by 3.5 sp1.
Have no idea how to fix that, any ideas? thank you.
CellVM class:
[Serializable]
public class CellVM:ANotifyPropertyChanged
{
public Cell model;
public int X
{
get { return model.X; }
set { model.X = value; OnPropertyChanged("X"); }
}
public int Y
{
get { return model.Y; }
set { model.Y = value; OnPropertyChanged("Y"); }
}
public string Value
{
get
{
return model.ActualValue;
}
set { model.ActualValue = value; OnPropertyChanged("Value"); }
}
[NonSerialized]
private bool _isActive;
public bool IsActive
{
get
{
return _isActive;
}
set
{
_isActive = value;
OnPropertyChanged("IsActive");
OnPropertyChanged("BackgroundBrush");
OnPropertyChanged("HighlightBrush");
}
}
public bool IsReadOnly
{
get
{
if(model.InitialValue.Equals(model.RightValue))
{
return true;
}
return false;
}
}
public bool IsHighLighted
{
get;
set;
}
private bool _isInvalid;
public bool IsInvalid
{
get { return _isInvalid; }
set
{
_isInvalid = value;
OnPropertyChanged("IsInvalid");
OnPropertyChanged("BackgroundBrush");
}
}
private bool _isValueMode;
public bool IsValueMode
{
get
{
return _isValueMode;
}
set
{
_isValueMode = value;
OnPropertyChanged("IsValueMode");
OnPropertyChanged("ValueVisibility");
OnPropertyChanged("PossibilityVisibility");
}
}
[NonSerialized]
private FontWeight _valueFontWeight;
public FontWeight ValueFontWeight
{
get
{
return _valueFontWeight;
}
set { _valueFontWeight = value; OnPropertyChanged("ValueFontWeight");}
}
[NonSerialized]
private Brush _valueColor;
public Brush ValueColor
{
get
{
if(_valueColor == null)
{
return new SolidColorBrush(Colors.Black);
}
return _valueColor;
}
set { _valueColor = value; OnPropertyChanged("ValueColor"); }
}
public Visibility ValueVisibility
{
get
{
if(IsValueMode)
{
return Visibility.Visible;
}
return Visibility.Hidden;
}
}
public Visibility PossibilityVisibility
{
get
{
if (!IsValueMode)
{
return Visibility.Visible;
}
return Visibility.Hidden;
}
}
private bool _isCheckInvalid;
public bool IsCheckInvalid
{
get
{
return _isCheckInvalid;
}
set
{
_isCheckInvalid = value;
OnPropertyChanged("IsCheckInvalid");
OnPropertyChanged("HighlightBrush");
}
}
public Brush HighlightBrush
{
get
{
if(IsActive && IsReadOnly)
{
return ColorManager.CellActive;
}
if (IsCheckInvalid)
{
ColorAnimation animation = new ColorAnimation
{
From = Colors.Firebrick,
To = Colors.WhiteSmoke,
Duration = new Duration(TimeSpan.FromSeconds(1)),
AutoReverse = true
};
SolidColorBrush brush = new SolidColorBrush(Colors.Firebrick);
animation.RepeatBehavior = RepeatBehavior.Forever;
animation.AccelerationRatio = 0.5;
brush.BeginAnimation(SolidColorBrush.ColorProperty, animation);
return brush;
}
return new SolidColorBrush(Colors.Transparent);
}
}
public Brush BackgroundBrush
{
get
{
if (IsActive)
{
if (!IsReadOnly)
{
return ColorManager.CellActive;
}
}
if (IsInvalid)
{
return ColorManager.CellInvalid;
}
if (IsHighLighted)
{
return ColorManager.CellHighlighted;
}
return new SolidColorBrush(Colors.White);
}
}
[NonSerialized]
private Brush _backgroundAnimationBrush;
public Brush BackgroundAnimationBrush
{
get { return _backgroundAnimationBrush; }
set { _backgroundAnimationBrush = value; OnPropertyChanged("BackgroundAnimationBrush"); }
}
public Brush PossibilitiesBrush
{
get
{
return new SolidColorBrush(PossibilitiesColor);
}
}
private Colour _possibilitiesColor;
public Colour PossibilitiesColor
{
get
{
if (_possibilitiesColor == null)
{
return new Colour(Colors.Black);
}
return _possibilitiesColor;
}
set
{
_possibilitiesColor = value;
OnPropertyChanged("PossibilitiesColor");
OnPropertyChanged("PossibilitiesBrush");
}
}
public ObservableCollection<string> Possibilities
{
get { return model.Possibilities; }
set
{
model.Possibilities = value;
OnPropertyChanged("Possibilities");
OnPropertyChanged("PossibilityVisibility");
}
}
private string _toolTip;
public string ToolTip
{
get { return _toolTip; }
set { _toolTip = value; OnPropertyChanged("ToolTip"); }
}
public CellVM(Cell model,bool isHighlighted)
{
this.model = model;
IsValueMode = true;
IsHighLighted = isHighlighted;
}
public void signalError(string message)
{
ToolTip = message;
IsInvalid = true;
}
public void resetError()
{
if(IsCheckInvalid)
{
return;
}
ToolTip = null;
IsInvalid = false;
}
public void AnimateError()
{
ColorAnimation animation = new ColorAnimation
{
From = Colors.Firebrick,
To = Colors.Transparent,
Duration = new Duration(TimeSpan.FromSeconds(1.5)),
AutoReverse = false
};
animation.Completed += new EventHandler(animation_Completed);
SolidColorBrush brush = new SolidColorBrush(Colors.Transparent);
animation.AccelerationRatio = 0.5;
BackgroundAnimationBrush = brush;
brush.BeginAnimation(SolidColorBrush.ColorProperty, animation);
}
public void AnimateHint()
{
ColorAnimation animation = new ColorAnimation
{
From = Colors.DarkGreen,
To = Colors.Transparent,
Duration = new Duration(TimeSpan.FromSeconds(1.5)),
AutoReverse = false
};
animation.Completed += new EventHandler(animation_Completed);
SolidColorBrush brush = new SolidColorBrush(Colors.Transparent);
animation.AccelerationRatio = 0.5;
BackgroundAnimationBrush = brush;
brush.BeginAnimation(SolidColorBrush.ColorProperty, animation);
}
private void animation_Completed(object sender, EventArgs e)
{
BackgroundAnimationBrush = null;
}
}
CellVM SuperClass (ancestor):
[Serializable]
public abstract class ANotifyPropertyChanged : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
}
Try out marking event PropertyChanged by [NonSerialized] attribute
below is syntax for events: (see MSDN)
[field:NonSerializedAttribute()]
public event ChangedEventHandler Changed;