How do I raise a ondraw event
Scenario: I am using a custom combobox with a onDrawItem in my form.
The drawitem is such
protected override void OnDrawItem(DrawItemEventArgs e)
{...
}
Question: How do I make the custom combobox ComboLineStyle redraw
itself on selectedindex changed of another cmbBoxLineColor. Ultimately I need a way to redraw all rows of the combobox on every selectedindex changed
.
private void cmbBoxLineColor_SelectedIndexChanged(object sender, EventArgs e)
{
Here I want the custom combobox-ComboLineStyle control to redraw itself
}
EDIT
I need the dropdown to draw itself again when the color in another linecolorcombo changes.Color
lineColorSel = cmbBoxLineColor.SelectedValue;
ComboBoxItemLineStyle itemSolid = new ComboBoxItemLineStyle ("Solid Line", lineColorSel);
The color property in my linestylecomboboxitem will have the selectedvalue of the linecolor combo. So the linestyle combo should refresh/invalidate itself and redraw itself with this lineColorSel.
Thank u
You can call Invalidate() on anything that inherits System.Windows.Forms.Control to force it to redraw
Heres and example of how I would do a custom draw for a selected item
protected override void OnDrawItem(DrawItemEventArgs e)
{
if (e.State == DrawItemState.Selected)
{
...
}
else
{
...
}
//or you could do it like this
//if(e.Index == this.SelectedIndex)
//{
//}
...
}
protected override void OnSelectedIndexChanged(EventArgs e)
{
base.OnSelectedIndexChanged(e);
base.Invalidate();
}
Related
I am using a DataRepeater control to show a popup. I am able to set BackColor of the current item by this code
private void dataRepeater1_CurrentItemIndexChanged(object sender, EventArgs e)
{
dataRepeater1.CurrentItem.BackColor = Color.Red;
}
but I am unable to add BackColor white for the previous item. Also I want to change the BackColor of the item form the list I am hovering mouse.
One way to solve this is to have one more property in your class, maybe called DataRepeater1_PreviousItem:
class YourClass
{
DataRepeaterItem DataRepeater1_PreviousItem { get; set; }
// ... some other code
private void dataRepeater1_CurrentItemIndexChanged(object sender, EventArgs e)
{
if (DataRepeater1_PreviousItem != null)
DataRepeater1_PreviousItem.BackColor = Color.White;
dataRepeater1.CurrentItem.BackColor = Color.Red;
DataRepeater1_PreviousItem = dataRepeater1.CurrentItem;
}
}
I'm trying to change the border color of a text box (txtUser) on button click event (something like a form validation, if the input is empty then call the method that colors the border red). I did some googling and found this:
void myControl1_Paint(object sender, PaintEventArgs e)
{
ControlPaint.DrawBorder(e.Graphics, this.txtUser.ClientRectangle, Color.Black, ButtonBorderStyle.Solid);
}
But I'm having trouble understaing where or how should I call this method, or methods with (object sender, PaintEventArgs e) as params. Any explanation is appreciated.
You need to inherit from TextBox and then override the OnPaint method. Something like this should work:
public class ValidateEdit : TextBox
{
bool _InError;
public ValidateEdit()
{
SetStyle(ControlStyles.UserPaint, true);
}
public bool InError {
get {
return _InError;
}
set
{
_InError = value;
Refresh();
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (InError)
ControlPaint.DrawBorder(e.Graphics, this.DisplayRectangle, Color.Red, ButtonBorderStyle.Solid);
}
}
I have a TextChanged event on my ComboBox like;
private void comboBox1_TextChanged(object sender, EventArgs e)
{
foreach (var item in comboBox1.Items.Cast<string>().ToList())
{
comboBox1.Items.Remove(item);
}
foreach (string item in InputBox.AutoCompleteCustomSource.Cast<string>().Where(s => s.Contains(comboBox1.Text)).ToList())
{
comboBox1.Items.Add(item);
}
}
As an explanation, when I change the text of combobox, I want to get string values contains in AutoCompleteCustomSource on InputBox (which is TextBox).
It works fine when I search them but when I select the item, obviously TextChanged event triggered again and Text property of Combobox will reset.
How to solve this?
If I understood correctly then i think you want to hide the TextChange event of the combobox. If it is then you can create a custom control inherited by ComboBox and override the TextChange event.
public partial class MyCombo : ComboBox
{
public MyCombo()
{
InitializeComponent();
}
bool bFalse = false;
protected override void OnTextChanged(EventArgs e)
{
//Here you can handle the TextChange event if want to suppress it
//just place the base.OnTextChanged(e); line inside the condition
if (!bFalse)
base.OnTextChanged(e);
}
protected override void OnSelectionChangeCommitted(EventArgs e)
{
bFalse = true;
base.OnSelectionChangeCommitted(e);
}
protected override void OnTextUpdate(EventArgs e)
{
base.OnTextUpdate(e);
bFalse = false; //this event will be fire when user types anything. but, not when user selects item from the list.
}
}
EDITED:
Another simple soution is use TextUpdate event instead of TextChange and keep your combobox as it is without creating another custom control.
private void myCombo1_TextUpdate(object sender, EventArgs e)
{
foreach (var item in myCombo1.Items.Cast<string>().ToList())
{
myCombo1.Items.Remove(item);
}
foreach (string item in myCombo1.AutoCompleteCustomSource.Cast<string>().Where(s => s.Contains(myCombo1.Text)).ToList())
{
myCombo1.Items.Add(item);
}
}
TextUpdate event will call only when user types anything in combobox. But, not when user selects item from the drop down list. So, this will not resent the added items.
You can also change the where condition if you wish to return all matched items in both cases(Upper and Lower). Suppose you have a two items in the list 1. Microsoft Sql Server, 2. microsoft office then what would be the result if i type microsoft only.
Where(s => s.ToLower().Contains(comboBox1.Text.ToLower()))
Sample Code
As #Sayse already said:
Add a boolean:
private bool codeCalled = new bool();
In your textChanged:
if(codeCalled == true)
{
codeCalled = false;
return;
}
else
{
codeCalled = true;
//your foreachcode here
}
That should do the trick.
Tested and is working.
Also tested and working, also not elegant:
private void textBox_TextChanged(object sender, EventArgs e)
{
textBox.TextChanged -= textBox_TextChanged;
//yourcode
textBox.TextChanged += textBox_TextChanged;
}
I created a class that inherits ToolStripSystemRenderer and have added overriden various events to style my toolstrip the way I want. But I can't seem to change background of a button's dropdown menu, without changing the background color of the toolstrip itself.
Here's an example of the menu. I want to change that system color.
My renderer class is pretty simple at the moment.
public class AvertToolStripRenderer : ToolStripSystemRenderer
{
protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e)
{
//base.OnRenderToolStripBorder(e);
}
protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
{
e.TextColor = Color.Black;
base.OnRenderItemText(e);
}
protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e)
{
e.ArrowColor = Color.White;
base.OnRenderArrow(e);
}
}
You need to set the renderer of your toolstrip(just in case you forgot about this detail):
YourToolstrip.Renderer = new AvertToolStripRenderer();
Next on your custom renderer class:
public class AvertToolStripRenderer : ToolStripProfessionalRenderer
{
//rest of your implementation...
protected override void OnRenderToolStripBackground(ToolStripRenderEventArgs e)
{
ToolStripDropDown dr = e.ToolStrip as ToolStripDropDown;
if (dr != null)
{
e.Graphics.FillRectangle(Brushes.Beige, e.AffectedBounds);
}
}
}
In my WPF application,I need to highlight ListViewItem whenever something is about to drop on it. I override OnDragEnter, OnDragOver, OnDragLeave etc of ListViewItem to apply my styles(say change background). It is working fine. but after dropping somthing on a listview item, when i click the listview items the selection and mouseover effects are not working properly.How can i solve this?
public class CustomListViewItem : ListViewItem
{
protected override void OnDragOver(System.Windows.DragEventArgs e)
{
this.Background = Brushes.Green;
base.OnDragOver(e);
}
protected override void OnDragEnter(System.Windows.DragEventArgs e)
{
this.Background = Brushes.Green;
base.OnDragEnter(e);
}
protected override void OnDragLeave(System.Windows.DragEventArgs e)
{
if (!this.IsSelected)
{
this.Background = Brushes.Transparent;
this.BorderBrush = Brushes.Transparent;
}
base.OnDragLeave(e);
}
}
After doing DragDrop your local value has precedence over selection and mouseover effects by style (see Dependency Property Setting Precedence List
).
Try DependencyObject.ClearValue Method:
protected override void OnDragLeave(System.Windows.DragEventArgs e)
{
if (!this.IsSelected)
{
this.ClearValue(BackgroundProperty);
this.ClearValue(BorderBrushProperty);
}
base.OnDragLeave(e);
}