|
Actually, both the Enter key behavior and validation work the same way - the control has to lose the focus (for validation) or the change has to be committed (by hitting the Enter key, which calls the set accessor of the Text property). See the documentation for the UpDownBase.UserEdit property in the .NET Framework SDK for a discussion of this behavior.
A good way to solve this would be to extend the NumericUpDown control and override either IsInputChar or IsInputKey , which are called with each key-down. Validate the entire number, though - not just the char or Keys that was passed to the method. Then change your code to instantiate this new control instead of the NumericUpDown . It's still a NumericUpDown control, though - you only extended it.
One other way is handle each NumericUpDown.KeyDown event (inherited from Control ) with the same handler, in which case you could do something like this:
numericUpDown1.KeyDown += new KeyEventHandler(ValidateNumber);
numericUpDown2.KeyDown += new KeyEventHandler(ValidateNumber);
private void ValidateNumber(object sender, KeyEventArgs e)
{
NumericUpDown nud = sender as NumericUpDown;
if (nud != null)
{
int value = int.Parse(nud.Text);
if (value < nud.Minimum || value > nud.Maximum)
e.Handled = true;
}
} As the comment said, you should also take things into account like the NumericUpDown.ThousandsSeparator and the like. You can use Int32.Parse (or Int64.Parse ) using the overload that uses the NumberFormatStyles as the second parameter. Do a bit-wise OR to construct the enum that you'll pass using the properties of the NumericUpDown control.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
hm.... Thank you so much for your reply, Heath.
I just got an idea from your reply; instead of extenting the control, I would prefer using same handler for my UpdownControls. As I have 10 updowncontrols, so I assigned the same Validating handler for each of them.
private void UpDownValidating(object sender, System.ComponentModel.CancelEventArgs e)
{
NumericUpDown nud = sender as NumericUpDown;
if(nud != null)
{
if(nud.Value < nud.Minimum)
nud.Value = nud.Minimum;
if(nud.Value > nud.Maximum)
nud.Value = nud.Maximum;
}
}
but I don't know will it cause any hidden effect? I think this method is better and simpler for me..
One more question,
Do you know any article that teaching us to make own control library. The idea is I want to make my own controls in my home, so that sometimes they can be used in my project by just import the control library.
Thanks a lot~~
|
|
|
|
|
Why would there be any "hidden side effect"? This is a perfectly reasonable solution, although I'd prefer encapsulation because it makes for a better OO design and doesn't force you to handle your events each time (which one could forget).
Developing a control library is trivial. In VS.NET, start a new Windows Control Library. Really, all this is is a DLL project, it just starts you off with a single control (with a bad name - so don't use it). Develop your controls and components deriving from the appropriate control and component classes. Don't forget to add decent designer support. There's a good, extensive section in MSDN that describes various base classes, attributes, and other design-time features that you should take into account for a good component library. See Developing Components[^].
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi
I sent a solution for this problem to Ronboy in the message boards. Have a look there. hopefully it helps you.
bye
HuseyinAltindag
|
|
|
|
|
Hi,
Anyone have any ideas about generating/displaying reports in VC#.Net without using Crystal Reports? For example, is there a way to use MS Access reports?
Or is there a way to use a stand-alone Crystal Reports file. I'm using Visual Studio Standard, and there is nothing for Crystal Reports included with it.
Any ideas are appreciated.
Matt
|
|
|
|
|
|
Hi !
(calling an ActiveX thing from Delphi 7)
Any clues as to why I am getting the following error msg ?
error msg; Undeclared identifier: 'Layer2'
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
|
|
|
This is the C# forum, no Delphi. Most likely, though, you can't declare a variable with a global scope inside a procedure. Not sure, though, since I don't know Delphi. That's why it's better to ask in a Delphi forum, which CodeProject doesn't have.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Thanks Heath,
I'll try a forum that has a Delphi section.
Cliff
|
|
|
|
|
I have a an application tha creates several usercontrols during runtime. The usercontrol is called "Clock", and for this matter, it contains a combobox called simply "comboBox1"
<br />
clocks=new Clock[4];<br />
for (int i=0; i<4; i++) <br />
{<br />
this.clocks[i]=new Times.Clock();<br />
this.clocks[i].Location = new System.Drawing.Point((i%2)*width, 136+(i/2)*112);<br />
this.clocks[i].Name = "clocks"+i;<br />
this.clocks[i].Size = new System.Drawing.Size(width, 112);<br />
this.clocks[i].TabIndex = 8+i;<br />
this.clocks[i].setSource(dsCities);<br />
this.Controls.Add(clocks[i]);<br />
}<br />
the dsCities is a DataSet that has one table.
now the problem is with the setSource function:
<br />
public void setSource(DataSet data)<br />
{<br />
this.comboBox1.DisplayMember="City";<br />
this.comboBox1.DataSource = data.Tables[0];<br />
this.comboBox1.SelectedIndex=0;<br />
}<br />
The function works fine for controls that where created on design-time, but doesn't seem to perform the data-binding itself when called from a run-time control.
Did anyone ever encounter this behavior?
Any help would be welcome.
|
|
|
|
|
At what point are you calling the DataBind method? At the Page_Load()?
Smitha
Every person, all the events of your life, are there because you have drawn them there. What you choose to do with them is up to you.
-- Richard Bach
|
|
|
|
|
This is a WinForm application, not a web-based one.
The data-binding is made after the call to the InitializeComponent() function, in the form's constructor.
|
|
|
|
|
Why not set a break-point at setSource and see if you have data or not.
- Nick Parker My Blog
|
|
|
|
|
Of course I set a breakpoint there. That's in the Debugging101 course.
The problem is that when I put a breakpoint in the setSource function, all I see is that the DataMemeber is set okay, but when the DataSource is assigned, its value doesn't change, and the value of DataMember if set to "".
I actually managed to solve this specific problem, by calling the setSource function only after the control was added to the form.
However, I did encounter the same problem somewhere else in the application, when I tried to add more clocks.
|
|
|
|
|
I have a problem that loads a dataset full of data and serves text to telnet clients. Everything in the program has worked well so far until now, whenever I go into this one function i just made, as soon as the first line hits, MOST of the class members dissapear!
I'm not really sure what kinds of information to provide except the watch result of one of the elements that goes BOOM:
BEFORE:
Name: dbGalaxy.Players Vaue: {GalaxyDatabase.glxDataset.PlayersDataTable}
AFTER:
Name: dbGalaxy.Players Value: error: cannot obtain value
Both the functions are within the main class (the server) and the dbGalaxy is also in this class. Why all of a sudden uppon entering a function, that an entire object and about 50 other members just simply dissapear...
Any ideas?
Philippe Durand
|
|
|
|
|
Euphorix wrote:
I'm not really sure what kinds of information to provide except the watch result of one of the elements that goes BOOM
How about some code snippets? Printing the watch state doesn't help solve anything.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I have a windows form that has four input text boxes. The input for each of these must be integers. Is there a way (e.g. property) that I can set which will only allow the user to enter intergers??? Thanks for any help.
|
|
|
|
|
Extend the TextBox with your own class (like NumericTextBox , for example) and override either IsInputChar or IsInputKey ). There are other ways involving overriding WndProc , but then you start getting into Windows notification messages which aren't necessary when the former two methods already encapsulate such functionality.
If you don't want to extend the class (and it's usually a good idea to encapsulate your logic rather than handle each instance of it separately), you could handle the KeyDown event of each TextBox (they could use the same handler, though).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi Ronboy,
There is a way doing that.What you need to do is :
-Fire a KeyPress event in properties for your TextBox
this.textBox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBox_KeyPress);
private void textBox_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
if (!Char.IsDigit(e.KeyChar) && e.KeyChar !=(char)8)
e.Handled=true;
}
So you can enter now in the TextBox ONLY integers AND Backspace-key with (char)8 .
e.KeyChar means it gets the char which is correspending to the key you pressed.
e.Handled=true; means if you entered a non-integer value(0-9) you don´t pass
this char to control element(TextBox).
good coding
Bye
Huseyin Altindag
Huseyin Altindag
|
|
|
|
|
have a web browser control attched to a win form. Now I have to capture the mousemove event,mouseclick event and keypress event ,, the moment someone moves his mouse or press a key on the document , I should be able to capture the event. I could able to capture the mouse move and mouse click but no key press. I have to somehow capture the keypress event. I donot know how and it is very urgent. Any help would be really appreciated. follwing is my partial code .
private void Form1_Load(object sender, System.EventArgs e)
{
object oURL = "http://www.google.com";
object oEmpty = "";
axWebBrowser1.Navigate2(ref oURL, ref oEmpty, ref oEmpty, ref oEmpty, ref oEmpty);
}
private void DocumentComplete(object sender,AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent e)
{
mshtml.HTMLDocument doc;
doc=(mshtml.HTMLDocument)axWebBrowser1.Document;
mshtml.HTMLDocumentEvents2_Event iEvent;
iEvent=(mshtml.HTMLDocumentEvents2_Event)doc;
iEvent.onclick+=new mshtml.HTMLDocumentEvents2_onclickEventHandler(ClickEventHandler);
iEvent.onmouseover += new mshtml.HTMLDocumentEvents2_onmouseoverEventHandler(MouseOverEventHandler);
iEvent.onkeypress+= new mshtml.HTMLDocumentEvents2_onkeypressEventHandler(KeyPressEventHandler);
iEvent.onkeydown+= new mshtml.HTMLDocumentEvents2_onkeydownEventHandler(KeyDownEventHandler);
listBox1.Items.Clear();
}
private bool ClickEventHandler(mshtml.IHTMLEventObj e)
{
if( e.srcElement.tagName == "INPUT" )
{
}
listBox1.Items.Insert(0, e.type + ":" + e.clientX.ToString()+","+e.clientY.ToString());
return true;
}
private void MouseOverEventHandler(mshtml.IHTMLEventObj e)
{
listBox1.Items.Insert(0, e.type + ":" + e.x.ToString()+","+ e.y.ToString());
}
private bool KeyPressEventHandler(mshtml.IHTMLEventObj e)
{
listBox1.Items.Insert(0,e.type + ":" + e.srcElement.recordNumber.ToString());
return true;
}
private void KeyDownEventHandler(mshtml.IHTMLEventObj e)
{
listBox1.Items.Insert(0,e.type+":"+e.srcElement.innerText.ToString() );
}
How can I capture the Key Press Event.
Thanks
Moloy
|
|
|
|
|
Do we have C# equivalent of Visual Basic
Public Property Get Price(Index As Integer) As Variant
End sub
In other words can we pass index to property procedure in C#
|
|
|
|
|
No C# does not support properties with parameters.
The only one it has is indexers with parameters, but those are nameless and you have to use array syntax:
public object this[int index]
{
get {... }
}
object value = MyObject[index];
|
|
|
|
|
You have to create an indexer into the class. For your example, Price on an object, it could refer to a PriceCollection :
public class PriceCollection : ICollection, IEnumerable
{
private ArrayList _prices = new ArrayList();
public Decimal this[int index]
{
get { return (Decimal)_prices[index]; }
put { _prices[index] = value; }
}
public int Count { get { return _prices.Count; } }
public bool IsFixedSize { get { return _prices.IsFixedSize; } }
public bool IsReadOnly { get { return _prices.IsReadOnly; } }
public bool IsSynchronized { get { return _prices.IsSynchronized; } }
public object SyncRoot { get { return _prices.SyncRoot; } }
public void CopyTo(Array array, int index)
{
_prices.CopyTo(array, index);
}
public IEnumerator GetEnumerator() { return _prices.GetEnumerator(); }
public int Add(Decimal price)
{
return _prices.Add(price);
}
public void Remove(int index)
{
_prices.RemoveAt(index);
}
}
This way, your object can have a Price property which is a type-safe collection, and allows what you asked:
public class MyObjectWithPrices
{
private PriceCollection _prices = new PriceCollection();
public PriceCollection Prices { get { return _prices; } }
}
Now if you have an instance of MyObjectWithPrices , myInstance , you can do fun things like:
Decimal price = myInstance.Prices[4];
Or
foreach (Decimal price in myInstance.Prices)
{
Console.WriteLine(price.ToString("C"));
}
Or
for (int i = 0; i < myInstance.Prices.Count; i++)
{
Console.WriteLine("{0} = {1}", i,
((Decimal)myInstance.Prices[i]).ToString("C"));
}
Using type-safe collections is a good idea.
|
|
|
|
|
In an application I am working on, I have a form that on startup, loads my addin structure and some other useful static classes. When I watch Task Manager during the form's startup, it starts up using 13500K of memory. If I minimize the form, it shoots down to 300K. Then when I restore it, it goes to only 1000K. If I start the form minimized, it still starts up taking 13500K. Then when I restore it, if jumps up 13600K. Then when I minimize it again, it drops back to 300K and up to 1000K when I restore it. Is there a way to avoid this form using so much memory on startup without having to minimize it and restore it? Thanks
|
|
|
|
|
Try using .NET framework 1.1 (This is assuming that you are using 1.0 under XP).
|
|
|
|