Hello together!
I need to have a numerical editor which does cover the range from minimal 100 to maximal 15000 in steps of 100 with a spin button and as user entry over the keyboard.First I tried an UltraNumericEditor which is working fine, but the user can enter values like 12385. I found no input mask which forces the entry to xxx00.
Then I tried an UltraMaskedEdit and used an input mask ‘nnn00’. This works quite well, but if the user is typing in 15000 the UltraMaskedEdit shows only 1500. The problem with this mask is any occurrence of a zero in the user input.
So please has anybody a good idea for an input mask which is solving the demand?
I’m using: Infragistics4.Win.UltraWinMaskedEdit.v15.2 15.2.20152.2023I have attached a simple example which shows both controls.
Thank you very much for any suggestion!
RegardsFrank
'nnn00' is one of the most appropriate mask, to work along with the Spin Increment where numbers can be entered from right to left and no empty place holders are kept in between for missing numbers.
Having # or 9 in place of n, keep empty spaces as place holders for digits and numbers are entered from left to right which makes it hard to spin increment and type in values.
I will also be enquiring more on this and will update you if I have a better answer.
One option, is to use the same Numeric Editor and validate the value user enters and round it to the nearest 100's. For that all you need to do is update the ultraNumericEditor1_ValueChanged event with one line of code as,
private void ultraNumericEditor1_ValueChanged( object sender, EventArgs e ){ if( ultraNumericEditor1 != null ) { int nValue = SaveObject2Int32(ultraNumericEditor1.Value); f (nValue > 0) { DebugWriteLine(nValue.ToString()); } ultraNumericEditor1.Value = Math.Round(nValue / 100d, 0) * 100; }}
Thanks,Josheela
Hi Josheela,
Thank you very much for your suggestions.
ultraNumericEditor1.Value = Math.Round(nValue / 100d, 0) * 100;
I have already this rounding solution in my real application. The only disadvantage is that the updated value is only getting visible if the ultraNumericEditor1 is losing the input focus. The main problem from the view of the programmer is, that we don’t really know when the user has competed his input.
I am still hoping that we can find an input mask which can solve this in a more elegant way.
Best regardsFrank
Hi Frank, Instead of the ValueChanged event, there is also the [Before|After]ExitEditMode events. Or if you have the AlwaysInEditMode property set to true, you can use the LostFocus or Validating events. All of those trigger when the editor loses focus. Which would likely be the ideal time to round the values.
Let me know if that helps,
Hi Michael
The events BeforeExitEditMode, AfterExitEditMode and Validating do all occur when the ultraNumericEditor control has lost its input focus. One possibility would be starting a timer after the ValueChanged event and then guessing let’s say after 10 seconds this was the last user input key stroke and then doing the rounding. But we do all know this is not a good solution.
If the ultraNumericEditor would allow an input mask like “nnn00” then it would be solved. But the Visual Studio tells me: “The specified mask is not compatible with the current value of the 'NumericType' property.”
Thank you very much for your suggestions!
Hi Frank,
The reason why the "nnn00" won't work is based on how the UltraMaskedEditor looks at the 0's as literals. Similar to dashes in a IP Address so in that scenario when you type a period (.) that matches the next literal it skips to the next section. In this case when you try to type 15000, the first zero you type matches the literal '0' in your mask. There in lies the problem that you are facing.http://es.infragistics.com/help/winforms/infragistics4.win.ultrawinmaskededit.v16.2~infragistics.win.ultrawinmaskededit.ultramaskededit~inputmask Since you want static zero's and not just a guaranteed to display character like $9990.00 where typing .1 will display $0.10. In that scenario they are just placeholders, that fill in the value zero if you don't otherwise have a value. But you specifically want the value "00". The three resolutions, that I think have the best resolution would be one, the BeforeExitEditMode, round the value. Drawback,end user would likely want some notification of the rounding, which you could display somewhere but may not be the ideal UI.Second validating, if the value includes zeros you can flip a data error flag. End user gets notification of the why, but may not like the display style.Third would take more coding, but you can fake it, by making the mask something like nnn~~ or some other unlikely character. Then you can create a DrawFilter that paints the '0' in place of the other character. Additionally I believe you will likely need to do either a dataFilter, to handle the data conversion of the editor string value of 150~~ to\from integer value 15000 of the underlying datasource. You could probably also use the before[Enter|exit]editmode events to do the same effect.
http://help.infragistics.com/Help/Doc/WinForms/2012.2/CLR4.0/HTML/Win_Draw_Filter.htmlhttp://devcenter.infragistics.com/Support/KnowledgeBaseArticle.aspx?ArticleID=5014Let me know if that helps,
Hi Mike
I did try to follow your suggestion with the draw filter but I did not find out how to draw the “0” instead of “~” for the given input mask “nnn~~”.How do I get the right object for the replacing of the characters inside the DrawElement method?
public bool DrawElement( Infragistics.Win.DrawPhase drawPhase, ref Infragistics.Win.UIElementDrawParams drawParams )Can this be a way?
UIElement hElement = drawParams.Element;MaskedEditControlUIElement hff = hUIElement as MaskedEditControlUIElement;.......
At the moment this is the code in the DrawElement method.
public bool DrawElement( DrawPhase drawPhase, ref UIElementDrawParams drawParams ){ string strGet = ultraMaskedEdit1.Text; string strOut = DoReplaceThisChar( strGet, "~" ); //ultraMaskedEdit1.Value = strOut; // this does not work! InfoMessage( "original={0} strOut={1}", strGet, strOut ); return( true );}
InfoMessage shows:original=145~~ strOut=14500
Thank you very much!
Hi Mike,
I changed the replacement character to an 'o' and checked it quickly on three different virtual machines. It is now more than good enough.
Thank you very much indeed for your worthful helping!
Regards Frank
I think that will be extremely difficult. I think the problem is that the measurement of the text is measuring the actual text of the character and then you are drawing a different character. You could try changing the replacement character to some other character and if you are lucky, you might find a character that has exactly the same width as the '0' which is being drawn. But whether there is such a character and whether that will work on all machines is something I can't be sure of.
Another approach you could take is drawing both 0s at once. So what you would have to do in that case is that you would not draw the 0's inside the DisplayCharUIElement - you just do nothing in the DrawFilter for those elements so they draw nothing. Then you would have to use the DrawFilter to draw a string of "00" on the parent element. The challenge in that case would be lining up the 0's with the last digit before the 0. I'm not sure if that will actually work any better.
Frankly, if it were me, I would just remove the 0's from the MaskedEditor entirely and then put some text in a label that says "Hundreds of x's" or something like that. Not ideal from the UI perspective, but a lot easier to implement. :)
I have attached the sample with the changings.
Your recommendation with the ButtonsRight collection does work well. The last thing for a perfect solution would be closings the gap between the two last zeros. Is there a possibility to adjust the DrawFilter in that way that the gap can be closed?
I am completely aware that we shoot a little bit over the target of the normal behavior of the UltraEditMask. The end user does not really understand that we are facing a lot of pain solving his “simple” demand of stepping in increments +/-100.
Thank you so much for your help.
Actually... I take that back. There is a way to do it. :)
You could turn off the built-in spin buttons and then add your own using the ButtonsRight collection:
this.ultraMaskedEdit1.SpinButtonDisplayStyle = Infragistics.Win.SpinButtonDisplayStyle.None; this.ultraMaskedEdit1.ButtonsRight.Add(new SpinEditorButton()); this.ultraMaskedEdit1.EditorSpinButtonClick += UltraMaskedEdit1_EditorSpinButtonClick;
But then you have to handle the incrementing/decrementing of the values yourself in code:
private void UltraMaskedEdit1_EditorSpinButtonClick(object sender, SpinButtonClickEventArgs e) { string text = this.ultraMaskedEdit1.GetText(Infragistics.Win.UltraWinMaskedEdit.MaskMode.Raw); int initialValue = 0; if (false == string.IsNullOrEmpty(text)) initialValue = int.Parse(text); switch (e.ButtonType) { case SpinButtonItem.NextItem: this.ultraMaskedEdit1.Value = initialValue + 1; break; case SpinButtonItem.PreviousItem: this.ultraMaskedEdit1.Value = initialValue - 1; break; } }
private void UltraMaskedEdit1_EditorSpinButtonClick(object sender, SpinButtonClickEventArgs e) { string text = this.ultraMaskedEdit1.GetText(Infragistics.Win.UltraWinMaskedEdit.MaskMode.Raw); int initialValue = 0; if (false == string.IsNullOrEmpty(text)) initialValue = int.Parse(text);
switch (e.ButtonType) { case SpinButtonItem.NextItem: this.ultraMaskedEdit1.Value = initialValue + 1; break; case SpinButtonItem.PreviousItem: this.ultraMaskedEdit1.Value = initialValue - 1; break; } }