How to add Controls, as a toolbar, to a ContextMenuStrip? - c#

I'm making a Web Browser, but I don't know how to add these buttons on top of its ContextMenuStrip:
A Sepator make columns for all items, but no for only one line.
Do you have any idea how to make that?

Here's a custom Component, inheriting ToolStripControlHost (as the .Net's ToolStripTextBox, ToolStripComboBox etc.) that hosts an UserControl instead of a standard Control.
▶ Building an UserControl, you can add whatever other Controls to its surface and manage their actions as usual, except the UserControl's Events are exposed through the ToolStripControlHost derived object, so implementers don't need to know anything about the underlying hosted Control.
The hosted Control's events that you want to expose are subscribe to overriding OnSubscribeControlEvents() (and of course unsubscribed to overriding OnUnsubscribeControlEvents), then raising a related or composed event that returns values as needed.
▶ This is shown in the ToolStripControlHost class, see the public event EventHandler<UserActionArgs> ButtonAction event, an event that returns a custom EventArgs argument that includes elements that are needed to determine the action performed by the Button clicked.
When needed, the hosted Control is exposed through the ToolStripControlHost.Control property.
You can initialize an existing ContextMenuStrip (contextMenuStrip1, here) in the constructor of the Form that uses it:
public partial class Form1 : Form
{
private ToolStripUserControl toolStripUC = new ToolStripUserControl();
public Form1()
{
InitializeComponent();
// Assigns an existing ContextMenuStrip, to the Form or any other Control
this.ContextMenuStrip = contextMenuStrip1;
// Inserts the ToolStripUserControl and a Separator
contextMenuStrip1.Items.Insert(0, new ToolStripSeparator());
contextMenuStrip1.Items.Insert(0, toolStripUC);
// Subscribes to the ButtonAction event
toolStripUC.ButtonAction += (s, e)
=> { this.Text = $"Your Action is {e.UserAction}, triggered by {e.TriggerControl.Name}"; };
contextMenuStrip1.Closed += (s, e) => this.Text = "Right-Click on me";
}
}
ToolStripControlHost derived class:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
[ToolboxItem(false)]
public class ToolStripUserControl : ToolStripControlHost
{
// Pass the UserControl, MenuStripNavigationBar, to the base class.
public ToolStripUserControl() : base(new MenuStripNavigationBar()) { }
public MenuStripNavigationBar NavigatorBar => Control as MenuStripNavigationBar;
// Exposes the ButtonActions Dictionary, to redefine the Buttons' actions
public Dictionary<Control, ButtonAction> ButtonActions {
get => NavigatorBar.ButtonActions;
set => NavigatorBar.ButtonActions = value;
}
// Subscribe to the events you want to expose...
protected override void OnSubscribeControlEvents(Control ctl)
{
base.OnSubscribeControlEvents(ctl);
var navigatorBar = (MenuStripNavigationBar)ctl;
navigatorBar.UserAction += OnButtonAction;
}
// ...and then unsubscribe. This is called when the Form is destroyed
protected override void OnUnsubscribeControlEvents(Control ctl)
{
base.OnUnsubscribeControlEvents(ctl);
var navigatorBar = (MenuStripNavigationBar)ctl;
navigatorBar.UserAction -= OnButtonAction;
}
// Exposes a public custom event
public event EventHandler<UserActionArgs> ButtonAction;
// Raises the event when an UserAction is triggered
private void OnButtonAction(object sender, EventArgs e)
{
var ctl = sender as Control;
var userAction = new UserActionArgs(ButtonActions[ctl], ctl);
ButtonAction?.Invoke(this, userAction);
}
}
Custom EventArgs object:
public class UserActionArgs : EventArgs
{
public UserActionArgs(ButtonAction action, Control control)
{
this.UserAction = action;
this.TriggerControl = control;
}
public ButtonAction UserAction { get; }
public Control TriggerControl { get; }
}
Actions enumerator:
public enum ButtonAction
{
MoveBack,
MoveForward,
PlayMusic,
PlayAnimation
}
This is how it works:
This is the full UserControl, to ease testing:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
public partial class MenuStripNavigationBar : UserControl
{
public event EventHandler UserAction;
public MenuStripNavigationBar()
{
InitializeComponent();
this.ButtonActions = new Dictionary<Control, ButtonAction>();
this.buttonArrowLeft.Text = "⏪";
ButtonActions.Add(this.buttonArrowLeft, ButtonAction.MoveBack);
this.buttonArrowLeft.Click += ButtonsActionEvent;
this.buttonArrowRight.Text = "⏩";
ButtonActions.Add(this.buttonArrowRight, ButtonAction.MoveBack);
this.buttonArrowRight.Click += ButtonsActionEvent;
this.buttonMusicKey.Text = "♬";
ButtonActions.Add(this.buttonMusicKey, ButtonAction.PlayMusic);
this.buttonMusicKey.Click += ButtonsActionEvent;
this.buttonAction.Text = "⛄";
ButtonActions.Add(this.buttonAction, ButtonAction.PlayAnimation);
this.buttonAction.Click += ButtonsActionEvent;
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Dictionary<Control, ButtonAction> ButtonActions { get; set; }
private void ButtonsActionEvent(object sender, EventArgs e)
=> UserAction?.Invoke(sender, e);
[ToolboxItem(false)]
internal class ButtonPanel : Panel
{
private Color borderActiveColor = Color.LightSteelBlue;
private Color borderInactiveColor = Color.Gray;
private Color borderColor = Color.Transparent;
public ButtonPanel()
{
this.SetStyle(ControlStyles.Selectable | ControlStyles.SupportsTransparentBackColor |
ControlStyles.UserMouse | ControlStyles.StandardClick, true);
this.UpdateStyles();
this.BackColor = Color.Transparent;
}
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
this.OnEnter(e);
}
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
this.OnLeave(e);
}
protected override void OnEnter(EventArgs e)
{
base.OnEnter(e);
bool hovered = this.ClientRectangle.Contains(this.PointToClient(MousePosition));
borderColor = hovered ? Enabled ? borderActiveColor : borderInactiveColor : Color.Transparent;
this.Invalidate();
}
protected override void OnLeave(EventArgs e)
{
if (this.ClientRectangle.Contains(this.PointToClient(MousePosition))) return;
borderColor = Color.Transparent;
base.OnLeave(e);
this.Invalidate();
}
TextFormatFlags flags = TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter |
TextFormatFlags.NoPadding | TextFormatFlags.PreserveGraphicsClipping | TextFormatFlags.SingleLine;
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var textRect = Rectangle.Inflate(ClientRectangle, 0, -1);
TextRenderer.DrawText(e.Graphics, Text, Font, textRect, ForeColor, Color.Empty, flags);
ControlPaint.DrawBorder(e.Graphics, ClientRectangle, borderColor, ButtonBorderStyle.Solid);
}
}
}
Designer file:
partial class MenuStripNavigationBar
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
this.buttonAction = new MenuStripNavigationBar.ButtonPanel();
this.buttonArrowLeft = new MenuStripNavigationBar.ButtonPanel();
this.buttonArrowRight = new MenuStripNavigationBar.ButtonPanel();
this.buttonMusicKey = new MenuStripNavigationBar.ButtonPanel();
this.SuspendLayout();
//
// buttonAction
//
this.buttonAction.BackColor = System.Drawing.Color.Transparent;
this.buttonAction.Font = new System.Drawing.Font("Segoe UI Symbol", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.buttonAction.Location = new System.Drawing.Point(166, 2);
this.buttonAction.Name = "buttonAction";
this.buttonAction.Size = new System.Drawing.Size(42, 26);
this.buttonAction.TabIndex = 0;
//
// buttonArrowLeft
//
this.buttonArrowLeft.BackColor = System.Drawing.Color.Transparent;
this.buttonArrowLeft.Font = new System.Drawing.Font("Segoe UI Symbol", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.buttonArrowLeft.Location = new System.Drawing.Point(3, 2);
this.buttonArrowLeft.Name = "buttonArrowLeft";
this.buttonArrowLeft.Size = new System.Drawing.Size(42, 26);
this.buttonArrowLeft.TabIndex = 0;
//
// buttonArrowRight
//
this.buttonArrowRight.BackColor = System.Drawing.Color.Transparent;
this.buttonArrowRight.Font = new System.Drawing.Font("Segoe UI Symbol", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.buttonArrowRight.Location = new System.Drawing.Point(58, 2);
this.buttonArrowRight.Name = "buttonArrowRight";
this.buttonArrowRight.Size = new System.Drawing.Size(42, 26);
this.buttonArrowRight.TabIndex = 0;
//
// buttonMusicKey
//
this.buttonMusicKey.BackColor = System.Drawing.Color.Transparent;
this.buttonMusicKey.Font = new System.Drawing.Font("Segoe UI Symbol", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.buttonMusicKey.Location = new System.Drawing.Point(112, 2);
this.buttonMusicKey.Name = "buttonMusicKey";
this.buttonMusicKey.Size = new System.Drawing.Size(42, 26);
this.buttonMusicKey.TabIndex = 0;
//
// MenuStripNavigationBar
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.BackColor = System.Drawing.Color.Transparent;
this.Controls.Add(this.buttonMusicKey);
this.Controls.Add(this.buttonArrowRight);
this.Controls.Add(this.buttonArrowLeft);
this.Controls.Add(this.buttonAction);
this.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.MaximumSize = new System.Drawing.Size(212, 30);
this.MinimumSize = new System.Drawing.Size(212, 30);
this.Name = "MenuStripNavigationBar";
this.Size = new System.Drawing.Size(212, 30);
this.ResumeLayout(false);
}
private ButtonPanel buttonAction;
private ButtonPanel buttonArrowLeft;
private ButtonPanel buttonArrowRight;
private ButtonPanel buttonMusicKey;
}

Related

Is it possible to add a label on the zoomable picturebox image(fixed-size picturebox)?

I want to label or image on a factory map. When I click on this tag, I want to open the camera in that region. My points (labels) on the factory map should be erasable, movable, clickable. It is impossible to do this with DrawImage. Instead of using graphic draw image as an alternative way, I want to create a dynamic label and affect the image of the fixed size picturebox. But I can't assign 'pictureBox.Image' to the parent property for the label.
Where am I making mistakes. The picture box should be fixed and the picture in it should be zomable. But the label acts separately from the image. I request your help.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
using Cyotek.Windows.Forms.Properties;
namespace Cyotek.Windows.Forms
{
internal partial class ScaledAdornmentsDemoForm : BaseForm
{
#region Instance Fields
//private List<Point> _landmarks;
private List<Label> _landmarks;
private Bitmap _markerImage;
#endregion
#region Public Constructors
public ScaledAdornmentsDemoForm()
{
InitializeComponent();
}
#endregion
#region Overridden Methods
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
imageBox.ZoomToFit();
_markerImage = Resources.circle_24;
_landmarks = new List<Label>();
this.AddLabel(new Label() { Text = "", BackColor = Color.Transparent, Location = new Point(467, 447), Parent = imageBox, Image = _markerImage });
this.AddLabel(new Label() { Text = "", BackColor = Color.Transparent, Location = new Point(662, 262), Parent = imageBox, Image = _markerImage });
this.AddLabel(new Label() { Text = "", BackColor = Color.Transparent, Location = new Point(779, 239), Parent = imageBox, Image = _markerImage });
}
#endregion
#region Private Members
private void AddLabel(Label label)
{
Debug.Print("Added label: {0}", label);
//label.Location = new Point(label.Location.X - (label.Size.Width / 2), label.Location.Y - _markerImage.Size.Height);
// imageBox.Controls.Add(label);
_landmarks.Add(label);
}
#endregion
#region Event Handlers
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
//AboutDialog.ShowAboutDialog();
}
private void closeToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
private void imageBox_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
if (imageBox.IsPointInImage(e.Location))
{
this.AddLabel(new Label() { Text = "", BackColor = Color.Transparent, Location = e.Location, Parent = imageBox, Image = _markerImage });
}
}
}
private void imageBox_Paint(object sender, PaintEventArgs e)
{
Console.WriteLine();
foreach (Label label in _landmarks)
{
label.Location = imageBox.GetOffsetPoint(label.Location);
//imageBox.Controls.Add(label);
//e.Graphics.DrawImage(_markerImage, new Rectangle(location, markerSize), new Rectangle(Point.Empty, _markerImage.Size), GraphicsUnit.Pixel);
}
}
#endregion
}
}

Winform - Custom TextBox change backcolor when Readonly

Hi I have a custom TextEditor:
public partial class TextEditor : TextBox
{
public TextEditor() : base()
{
this.Font = new Font("Calibri", 12.0f);
this.BackColor = Color.Gainsboro;
this.BorderStyle = BorderStyle.FixedSingle;
if (this.ReadOnly)
{
this.BackColor = Color.DarkGray;
}
}
protected override void InitLayout()
{
base.InitLayout();
base.CharacterCasing = _charCasing;
//SetStyle(ControlStyles.UserPaint, true);
}
}
I would like to change its BackGroundColor when the property ReadOnly = true but its not working.
Any clue?
You are doing it on constructor. Which ReadOnly be default to False
What you need is listen to ReadOnlyChanged event
public partial class TextEditor : TextBox
{
public TextEditor()
{
this.Font = new Font("Calibri", 12.0f);
this.BackColor = Color.Gainsboro;
this.BorderStyle = BorderStyle.FixedSingle;
ReadOnlyChanged += OnReadOnlyChanged;
}
private void OnReadOnlyChanged(object sender, EventArgs eventArgs)
{
if (ReadOnly)
BackColor = Color.DarkGray;
}
protected override void InitLayout()
{
base.InitLayout();
CharacterCasing = _charCasing;
//SetStyle(ControlStyles.UserPaint, true);
}
}

KeyDown and KeyUp events on a custom UserControl

I have a UserControl that has inside some other controls and then a Panel that I use to paint custom shapes on mouse events. I would like to add some other functionalities but for that I would need to detect KeyDown and KeyUp while the mouse is drawing shapes on the Panel (in this situation UserControl.KeyDown/KeyUp never fire). How can be this achieved?
EDIT
Here is a minimum version for the UserControl where the problem can be seen:
public partial class UserControl1 : UserControl
{
TextBox textBox1;
Panel panel1;
public UserControl1()
{
InitializeComponent();
textBox1 = new System.Windows.Forms.TextBox();
textBox1.Location = new System.Drawing.Point(0, 0);
this.Controls.Add(this.textBox1);
panel1 = new System.Windows.Forms.Panel();
panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
panel1.Location = new System.Drawing.Point(0, 25);
panel1.Size = new System.Drawing.Size(300, 150);
panel1.MouseEnter += new System.EventHandler(this.panel1_MouseEnter);
this.Controls.Add(this.panel1);
this.Size = new System.Drawing.Size(300, 200);
this.KeyDown += UserControl1_KeyDown;
}
private void panel1_MouseEnter(object sender, EventArgs e)
{
panel1.Focus();
}
void UserControl1_KeyDown(object sender, KeyEventArgs e)
{
MessageBox.Show("Key down");
}
}
When this control is inside a Form the "Key down" message is never displayed.
I took the code from Hans Passant here (great hint, many thanks!) and I modified it to suit my needs as follow:
class SelectablePanel : Panel
{
public SelectablePanel()
{
this.SetStyle(ControlStyles.Selectable, true);
this.TabStop = true;
}
protected override bool IsInputKey(Keys keyData)
{
if (keyData == Keys.Up || keyData == Keys.Down) return true;
if (keyData == Keys.Left || keyData == Keys.Right) return true;
return base.IsInputKey(keyData);
}
protected override void OnKeyDown(KeyEventArgs e)
{
var handler = KeyDown;
if (handler != null) handler(this, e);
}
protected override void OnKeyPress(KeyPressEventArgs e)
{
var handler = KeyPress;
if (handler != null) handler(this, e);
}
protected override void OnKeyUp(KeyEventArgs e)
{
var handler = KeyUp;
if (handler != null) handler(this, e);
}
protected override void OnMouseEnter(EventArgs e)
{
this.Focus();
base.OnMouseEnter(e);
}
protected override void OnEnter(EventArgs e)
{
this.Invalidate();
base.OnEnter(e);
}
protected override void OnLeave(EventArgs e)
{
this.Invalidate();
base.OnLeave(e);
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
if (this.Focused)
{
var rc = this.ClientRectangle;
rc.Inflate(-2, -2);
ControlPaint.DrawFocusRectangle(pe.Graphics, rc);
}
}
[Browsable(true)]
public new event EventHandler<KeyEventArgs> KeyDown;
[Browsable(true)]
public new event EventHandler<KeyEventArgs> KeyUp;
[Browsable(true)]
public new event EventHandler<KeyPressEventArgs> KeyPress;
}
Finally I modified my original code like this:
public partial class UserControl1 : UserControl
{
TextBox textBox1;
SelectablePanel selectablePanel;
public UserControl1()
{
InitializeComponent();
textBox1 = new System.Windows.Forms.TextBox();
textBox1.Location = new System.Drawing.Point(0, 0);
this.Controls.Add(this.textBox1);
selectablePanel = new SelectablePanel();
selectablePanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
selectablePanel.Location = new System.Drawing.Point(0, 25);
selectablePanel.Size = new System.Drawing.Size(300, 150);
selectablePanel.KeyDown += panel1_KeyDown;
this.Controls.Add(this.selectablePanel);
this.Size = new System.Drawing.Size(300, 200);
}
void panel1_KeyDown(object sender, KeyEventArgs e)
{
MessageBox.Show("Key down");
}
}
and now it works for what I need.

How to autoscroll single line textbox continuous?

I need to write something to autoscroll a text in a single line TextBox continuously. Do I need to scroll to caret then set it to first char and start over?
So i found a marquee control and modify it a little and used it instead of textbox
public class Marquee : System.Windows.Forms.UserControl
{
private System.ComponentModel.IContainer components;
private System.Windows.Forms.Timer timer1;
private int currentPos = 0;
private bool mBorder;
private string mText;
public string MarqueeText
{
get { return mText; }
set { mText = value; }
}
public bool Border
{
get { return mBorder; }
set { mBorder = value; }
}
public int Interval
{
get { return timer1.Interval * 10; }
set { timer1.Interval = value / 10; }
}
public Marquee()
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
// TODO: Add any initialization after the InitForm call
this.Size = new Size(this.Width, this.Font.Height);
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.timer1 = new System.Windows.Forms.Timer(this.components);
//
// timer1
//
this.timer1.Enabled = true;
this.timer1.Interval = 1000;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
//
// Marquee
//
this.Name = "Marquee";
this.Size = new System.Drawing.Size(150, 136);
this.Resize += new System.EventHandler(this.Marquee_Resize);
}
#endregion
private void Marquee_Resize(object sender, System.EventArgs e)
{
this.Height = this.Font.Height;
}
private void timer1_Tick(object sender, System.EventArgs e)
{
this.Invalidate();
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
if (mBorder)
{
e.Graphics.DrawRectangle(new Pen(this.ForeColor), 0, 0, this.Width - 1, this.Height - 1);
}
float dif = e.Graphics.MeasureString(mText, this.Font).Width- this.Width;
if (this.Width < e.Graphics.MeasureString(mText, this.Font).Width)
{
e.Graphics.DrawString(mText, this.Font, new SolidBrush(this.ForeColor),
currentPos, 0);
e.Graphics.DrawString(mText, this.Font, new SolidBrush(this.ForeColor),
this.Width + currentPos + dif, 0);
currentPos--;
if ((currentPos < 0) && (Math.Abs(currentPos) >= e.Graphics.MeasureString(mText, this.Font).Width))
currentPos = this.Width + currentPos;
}
else
{
e.Graphics.DrawString(mText, this.Font, new SolidBrush(this.ForeColor),-dif/2, 0);
}
}
}
So if the text width is longer than the width of the control the text will be static else the text will auto-scroll

How to get event for ComboBox inside of Gridview

How to get event for ComboBox inside of Gridview using C# Windows Application... Anyone Tell me the solution of this problem.....
Thanks in Advance...
check this http://www.eggheadcafe.com/community/aspnet/2/10098379/gridview.aspx
I think you are looking at the wrong place. For value change event, you should use your class's property changed event that is bound to that specific column in the GridView. Because, when you change value in the ComboBoxColumn, it will in turn update the value in the object that is bound to that row.
Example:
Designer generated code
`partial class Form1
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.dataGridView1 = new System.Windows.Forms.DataGridView();
this.Column1 = new System.Windows.Forms.DataGridViewComboBoxColumn();
this.Column2 = new System.Windows.Forms.DataGridViewTextBoxColumn();
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
this.SuspendLayout();
//
// dataGridView1
//
this.dataGridView1.AllowUserToAddRows = false;
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.Column1,
this.Column2});
this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill;
this.dataGridView1.Location = new System.Drawing.Point(0, 0);
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.RowTemplate.Height = 24;
this.dataGridView1.Size = new System.Drawing.Size(282, 255);
this.dataGridView1.TabIndex = 0;
//
// Column1
//
this.Column1.DataPropertyName = "Value1";
this.Column1.HeaderText = "Column1";
this.Column1.Name = "Column1";
//
// Column2
//
this.Column2.DataPropertyName = "Value2";
this.Column2.HeaderText = "Column2";
this.Column2.Name = "Column2";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(282, 255);
this.Controls.Add(this.dataGridView1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.DataGridView dataGridView1;
private System.Windows.Forms.DataGridViewComboBoxColumn Column1;
private System.Windows.Forms.DataGridViewTextBoxColumn Column2;
}`
Code Behind
`public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// Column1 is
Column1.DataPropertyName = "Value1";
Column1.Items.AddRange(Enumerable.Range(1, 10).Select(i => i.ToString()).ToArray());
Column2.DataPropertyName = "Value2";
dataGridView1.DataError += new DataGridViewDataErrorEventHandler(dataGridView1_DataError);
dataGridView1.DataSource = (from obj in Enumerable.Range(1, 20)
select new Model() { Value1 = obj, Value2 = ("Value2 #" + obj.ToString()) }).ToList();
}
void dataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
System.Diagnostics.Debug.WriteLine(e.Exception.ToString());
}
}
class Model
{
protected Int32 _value1;
public Int32 Value1
{
get
{
return _value1;
}
set
{
// Here is your property change event
MessageBox.Show(value.ToString());
_value1 = value;
}
}
public String Value2 { get; set; }
}`

Categories

Resources