Showing posts with label WinForms. Show all posts
Showing posts with label WinForms. Show all posts

Friday, April 20, 2007

Create a Winforms ComboBox with a default text when nothing is selected.

Follow these easy steps to create a combox that shows a text instead of an empty line when nothing is selected


  • Create a new UserControl

  • in the code view make sure the Class Enherits from ComboBox instead of UserControl

  • In the default constructor set the DrawMode to OwnerDrawn.

  • Add two properties UnSelectedColor of type Color and UnSelectedText of type string

  • Override the OnDrawItem method


I will put a more detailed article on my personal homepage. Link will follow later.

Thanks to Richard Everett who provided me the example code

Tuesday, March 06, 2007

I came across an annoying little thing trying to trigger an event that updates the UI...

{"Cross-thread operation not valid: Control 'label1' accessed from a thread other than the thread it was created on."}


This happens because the UI runs in a specific thread. Now we create another thread and try to access the UI thread which throws the above exception. There is a solution in msdn but imo its not a good one.

Thus we need to marshal the event from one thread to the other thread as shown below.

the source (just create a new form called form1 and drag a label and a button on it):

ThreadComponent.cs


using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.ComponentModel;


namespace WindowsApplication3 {
public delegate void ShowSomethingHandler(string message);


public class ThreadedComponent {
private Thread _Thread;

public ThreadedComponent() {
_Thread = new Thread(Poll);
_Thread.Start();

}

private void Poll() {
int i = 0;
ISynchronizeInvoke invoker = ShowSomething.Target as ISynchronizeInvoke;
while(true) {
if(ShowSomething != null) {

//ShowSomething("Message N°:" + (++i));
if(!invoker.InvokeRequired) {
object[] args = {"Message N°:" + (++i)};
invoker.Invoke(ShowSomething, args);
} else {
ShowSomething("Message N°:" + (++i));
}


}
Thread.Sleep(1000);
}
}

public event ShowSomethingHandler ShowSomething;
}
}



Form1.cs

namespace WindowsApplication3 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e) {
ThreadedComponent c = new ThreadedComponent();
c.ShowSomething += new ShowSomethingHandler(c_ShowSomething);
}

void c_ShowSomething(string message) {
label1.Text = message;
}
}
}