Windows 8 - TextBox that only accepts numbers goes wrong - windows-8

here is my TextBox written in C# with Key Down event handler
private void TextBox_KeyDown(object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e)
{
//ONLY ACCEPTS NUMBERS
char c = Convert.ToChar(e.Key);
if (!c.Equals('0') && !c.Equals('1') && !c.Equals('2') && !c.Equals('3') && !c.Equals('4') &&
!c.Equals('5') && !c.Equals('6') && !c.Equals('7') && !c.Equals('8') && !c.Equals('9'))
{
e.Handled = true;
}
}
it does works preventing letters from a to z. However, if I enter symbols like !##$%^&*()_+, it stills accept them. What am I missing?

You can use Char.IsDigit
e. Handled = !Char.IsDigit(c);
But this won't help you much in case of copy\pasting.
Also check related question on the right. For example Create WPF TextBox that accepts only numbers
UPDATE
For letters only try
e.Handled = Char.IsLetter(c);

There is no reliable way to handle this on the key down or key up events because for some odd reason shift 4 which is the $ sign returns 4 not the key value.
The best workaround is to catch the value before it's used and check it is numeric then alert the user.
var IsNumeric = new System.Text.RegularExpressions.Regex("^[0-9]*$");
if (!IsNumeric.IsMatch(edtPort.Text))
{
showMessage("Port number must be number", "Input Error");
return;
}
In no way ideal but better that trying to teach your users that the dollar sign is now a number!

Try this code. But sometimes you see char that you pressed and it is removed immediately. Not the best solution but sufficient
private void TextBox_OnTextChanged(object sender, TextChangedEventArgs e)
{
var textBox = sender as TextBox;
if (textBox == null)
return;
if (textBox.Text.Length == 0) return;
var text = textBox.Text;
int result;
var isValid = int.TryParse(text, out result);
if (isValid) return;
var selectionStart = textBox.SelectionStart;
var resultString = new string(text.Where(char.IsDigit).ToArray());
var lengthDiff = textBox.Text.Length - resultString.Length;
textBox.Text = resultString;
textBox.SelectionStart = selectionStart - lengthDiff;
}

this might help, this is what I used.
private void txtBoxBA_KeyDown(object sender, KeyRoutedEventArgs e)
{
// only allow 0-9 and "."
e.Handled = !((e.Key.GetHashCode() >= 48 && e.Key.GetHashCode() <= 57));
// check if "." is already there in box.
if (e.Key.GetHashCode() == 190)
e.Handled = (sender as TextBox).Text.Contains(".");
}

Related

Skipping Tab Index on Non Editable column

How to allow Setting Tabindex within the c1 FlexGrid in such a way that it skips a particular column in the c1 FlexGrid.
Is there something I can too do this
Thanks!
There might be a better way, but here's one approach:
public partial class Form1 : Form
{
private Int32 _colIdxToSkip = 4; //Remember, there's an extra column if "Row Headers" are turned on!
private Keys _lastKeys = Keys.None;
public Form1()
{
InitializeComponent();
flexGrid.KeyActionTab = C1.Win.C1FlexGrid.KeyActionEnum.MoveAcross;
}
private void flexGrid_BeforeRowColChange(Object sender, C1.Win.C1FlexGrid.RangeEventArgs e)
{
if (_lastKeys == Keys.Tab && e.OldRange.r1 == e.NewRange.r1 && e.NewRange.c1 == _colIdxToSkip)
{
if (_colIdxToSkip == flexGrid.Cols.Count - 1)
{
flexGrid.Row = (flexGrid.Row == flexGrid.Rows.Count - 1 ? flexGrid.Rows.Fixed : flexGrid.Row + 1);
flexGrid.Col = flexGrid.Cols.Fixed;
}
else
flexGrid.Col = _colIdxToSkip + 1;
e.Cancel = true;
}
}
private void flexGrid_KeyDown(Object sender, KeyEventArgs e)
{
_lastKeys = e.KeyCode;
}
}

How to make keyCode == ENTER update a string?

I have my programme here, where you can see I have a string called "S", and a void Get Temperature. At the bottom where keypresses are processed, it has an else If statement with ENTER. I want it so that when you press enter, it updates the string (s) to whatever you have typed, and then load it into the "SetAddress" field. How would I go about this?
import com.temboo.core.*;
import com.temboo.Library.Yahoo.Weather.*;
import ddf.minim.*;
AudioPlayer player;
Minim minim;
PImage bg;
String myText;
PFont Bold;
PFont Thin;
TembooSession session = new TembooSession("goldsmiths-c", "myFirstApp", "CNgLbwqnqzGdsnk6wHXPfAnQNSmV0Fmr");
String s = "Enter Location";
int prev = frameCount;
//KeyPressed KeyPressed = new KeyPressed();
void setup() {
size(960, 540);
bg = loadImage("mountains.jpg");
minim = new Minim(this);
player = minim.loadFile("song.mp3");
player.play();
player.loop();
runGetTemperatureChoreo();
Bold = createFont ("TTFirsBlackItalic.otf", height);
Thin = createFont ("TTFirsThin.otf", height);
frameRate (30);
}
void draw() {
background(bg);
fill (0);
textFont (Bold);
textSize (48);
fill(255, 255, 255);
text(myText, 10, 390);
fill(255, 255, 255);
textFont (Thin);
textSize (48);
text(s, 10, 500);
print(mouseY);
}
void runGetTemperatureChoreo() {
GetTemperature getTemperatureChoreo = new GetTemperature(session);
getTemperatureChoreo.setAddress(s);
getTemperatureChoreo.setUnits("c");
GetTemperatureResultSet getTemperatureResults = getTemperatureChoreo.run();
myText = (s) + (getTemperatureResults.getTemperature() + ("°c"));
print(getTemperatureResults.getTemperature());
}
void keyPressed()
{
if (keyPressed && prev <= frameCount-10) { //If a key is being pressed, and the security/delay is fine with it
prev = frameCount; //re-Init the clock
if (keyCode == BACKSPACE) { //Delete a char!
if (s.length() > 0) {
s = s.substring(0, s.length()-1);
}
} else if (keyCode == DELETE) {
s = "";
} else if (keyCode == ENTER && s.length() != 0) {
} else if (keyCode != SHIFT && keyCode != CONTROL && keyCode != ALT && s.length() < 20) { //It's an ok char, add it to the String
s += key;
}
}
}
Well, it looks like you're storing what the user types in the s variable. You then have this part of your if statement:
else if (keyCode == ENTER && s.length() != 0) {
}
That else if will be entered whenever the user presses enter after typing something. So you just have to put whatever code you want inside the body of that statement:
else if (keyCode == ENTER && s.length() != 0) {
getTemperatureChoreo.setAddress(s);
}
I might not be fully understanding your code, so this is just an example. But the basic idea is the same: to do something when the user presses enter, just put the code you want to happen inside this else if block.
In the future, please try to post an MCVE instead of your entire sketch. For example, your question has nothing to do with minim, so you can get rid of all of that code. Start over with a blank sketch and only add enough code so we can copy and paste it to run it ourselves to see where you're stuck. Good luck.

How to Error Handle a NullReferenceException

My website went down for a few days, therefore I am trying to produce some error handling while the MVC app doesnt have access to certain resources so if something doesnt become unavailable again the WHOLE THING doesnt have to go down.
At the moment a controller is trying to access viewbag.moreNewProducts that isnt available.
public ActionResult Index(string search)
{
string[] newProductLines = this.getMoreNewProducts();
string[] newNews = this.getMoreNews();
string[] newPromotions = this.getMorePromotions();
string[] fewerProductLines = this.getLessNewProducts(newProductLines);
ViewBag.moreNewProducts = newProductLines;
ViewBag.moreNews = newNews;
ViewBag.morePromotions = newPromotions;
ViewBag.lessNewProducts = fewerProductLines;
bool disableShowMore = false;
This is where I run into an error: " foreach (string line in newProductLines)"
public string[] getLessNewProducts(string[] newProductLines)
{
int charCount = 0;
int arrayCount = 0;
string[] displayProductLines = new string[6];
bool continueWriting;
if (newProductLines == null)
{
foreach (string line in newProductLines)
{
continueWriting = false;
for (int i = 0; charCount < 250 && i < line.Length && arrayCount < 5; i++)
{
string index = newProductLines[arrayCount].Substring(i, 1);
displayProductLines[arrayCount] += index;
charCount++;
continueWriting = true;
}
if (continueWriting == true)
{
arrayCount++;
}
}
string[] LessNewProducts = new string[arrayCount];
for (int d = 0; d < arrayCount; d++)
{
LessNewProducts[d] = displayProductLines[d];
}
return LessNewProducts;
}
else
{
return null;
}
}
how do I get around an if else statement so the whole thing doesnt have to crash?
Two things.
Your if (newProductLines == null) statement has the wrong condition on it. I don't believe that you want to enter that if newProductLines is null. You can inverse this condition to get the desired result(if (newProductLines != null)).
If you run into another situation later where you need to catch an error, you can always use the try-catch block to catch exceptions that you are expecting.
try
{
//code that could cause the error here
}
catch(NullReferenceException nullRefExcep)
{
//what you want it to do if the null reference exception occurs
}
if (newProductLines == null)
should be replaced with if (newProductLines != null) so you don't have to handle the code with newProductLines as null. Basically, with this condition you will always have the NullReferenceException unless you manage your exception with a try catch block.
The real question to ask yourself is:
Why would newProductLines be null?
Presumably getMoreNewProducts() found a situation where it thought it would be appropriate to return a null value.
If this is happening because the system has an error that would make your page meaningless, then you may just want to change getMoreNewProducts() so that it throws an exception when that error state occurs. Typically it's safest and easiest to debug programs that fail as soon as they run into an unexpected situation.
If this is happening because there are no new products, then you should just return an empty collection, rather than null. All your code should work just fine after that, without the need for an if/else statement: it will return an empty array for LessNewProducts, which is probably correct.
However, let's assume that there's a situation that you're anticipating will occur from time to time, which will make it impossible for you to retrieve newProductLines at that time, but which you would like the system to handle gracefully otherwise. You could just use null to indicate that the value isn't there, but it's really hard to know which variables might be null and which never should be. It may be wiser to use an optional type to represent that getMoreNewProducts() might not return anything at all, so you can force any consuming code to recognize this possibility and figure out how to deal with it before the project will even compile:
public ActionResult Index(string search)
{
Maybe<string[]> newProductLines = this.getMoreNewProducts();
string[] newNews = this.getMoreNews();
string[] newPromotions = this.getMorePromotions();
Maybe<string[]> fewerProductLines = newProductLines.Select(this.getLessNewProducts);
Disclaimer: I am the author of the Maybe<> class referenced above.
Here are some additional improvements I'd suggest:
Don't use ViewBag. Instead, create a strongly-typed ViewModel so that you can catch errors in your code at compile-time more often:
var viewModel = new ReportModel {
newProductLines = this.getMoreNewProducts(),
newNews = this.getMoreNews(),
...
};
...
return View(viewModel);
Learn to use LINQ. It will simplify a lot of your very complicated code. For example, instead of:
string[] LessNewProducts = new string[arrayCount];
for (int d = 0; d < arrayCount; d++)
{
LessNewProducts[d] = displayProductLines[d];
}
return LessNewProducts;
... you can say:
string[] LessNewProducts = displayProductLines.Take(arrayCount).ToArray();
In fact, I think your entire getLessNewProducts() method can be replaced with this:
return newProductLines
.Where(line => line.Length > 0)
.Select(line => line.Substring(0, Math.Min(line.Length, 250)))
.Take(5);

Janus 4 GridEx disable rows

I have have a Janus 4 GridEx control which includes a checkbox column.
I need to be able to disable certain rows (i.e make them non selectable/greyed out) depending the value of a particular column. The data for the grid is loaded from a database.
Any help would be appreciated.
You have to utilize the LoadingRow and SelectionChanged events of the Janus Grid.
This is a sample code: ( Here I'm checking the value of a particular column to be divided by 2)
private void grdEx_LoadingRow(object sender, Janus.Windows.GridEX.RowLoadEventArgs e)
{
if (Convert.ToInt32(e.Row.Cells["ID"].Value) % 2 == 0)
{
e.Row.RowStyle = new GridEXFormatStyle(e.Row.Table.RowFormatStyle);
e.Row.RowStyle.BackColor = Color.Gray;
}
}
private void grdEx_SelectionChanged(object sender, EventArgs e)
{
if (Convert.ToInt32(grdEx.GetValue("ID")) % 2 == 0)
{
if (grdEx.Row >= 0)
{
if (grdEx.Row == grdEx.RowCount - 1)
grdEx.Row = grdEx.Row - 1;
else
grdEx.Row = grdEx.Row + 1;
}
}
}
Depending on the Checkbox column , just see the sample code:
private void grdEX1_FormattingRow(object sender, RowLoadEventArgs e)
{
if (e.Row.RowIndex > -1 && e.Row.RowIndex < grdEX1.RowCount)
{
for (int i = 0; i < grdEX1.RootTable.Columns.Count; i++)
{
if (!Convert.ToBoolean(e.Row.Cells["checkboxCol"].Value))//checked So editable
{
e.Row.Cells[i].FormatStyle = new GridEXFormatStyle() { BackColor = Color.LightGray };
}
else
{
e.Row.Cells[i].FormatStyle = null;
}
}
}
}
To prevent the editing if the row is not checked :
private void grdEX1_EditingCell(object sender, EditingCellEventArgs e)
{
if(!Convert.ToBoolean(grdEX1.GetValue("checkboxCol"))) //not checked
{
e.Cancel = true;
return;
}
}

vb.net color first char in cell

In VB .NET I have 3 characters which are added to a DataGridView cell depending on some calculations.
They are rank change arrows and work fine, but I want the up arrow to be green and the down arrow to be red.
Dim strup As String = "▲"
Dim strdown As String = "▼"
Dim strsame As String = "▬"
So in the cell a change of negative three will look like ▼3 and plus 3 will look like ▲3 where the text and symbol are different colors.
How can I change the color of the first character in DataGridView cell?
There is no easy way to do this if you have anything more than just the character in question in the cell (you would need to do some form of custom painting).
If you only have those characters then this is very easy with the CellFormatting event:
void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
e.CellStyle.Font = new Font("Arial Unicode MS", 12);
if (dataGridView1.Columns[e.ColumnIndex].Name == "CorrectColumnName")
{
if (e.Value == "▲")
e.CellStyle.ForeColor = Color.Green;
else if (e.Value == "▼")
e.CellStyle.ForeColor = Color.Red;
else
e.CellStyle.ForeColor = Color.Black;
}
}
If you do want different colors within the same cell then something like the following code is required (this handles the CellPainting event):
void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex == -1 || e.RowIndex == -1)
return;
if (dataGridView1.Columns[e.ColumnIndex].Name == "CorrectColumnName")
{
e.Paint(e.CellBounds, DataGridViewPaintParts.All & ~DataGridViewPaintParts.ContentForeground);
if (e.FormattedValue.ToString().StartsWith("▲", StringComparison.InvariantCulture))
{
RenderCellText(Color.Green, e);
}
else if (e.FormattedValue == "▼")
{
RenderCellText(Color.Red, e);
}
else
RenderCellText(SystemColors.WindowText, e);
e.Handled = true;
}
}
private void RenderCellText(Color color, DataGridViewCellPaintingEventArgs e)
{
string text = e.FormattedValue.ToString();
string beginning = text.Substring(0, 1);
string end = text.Substring(1);
Point topLeft = new Point(e.CellBounds.X, e.CellBounds.Y + (e.CellBounds.Height / 4));
TextRenderer.DrawText(e.Graphics, beginning, this.dataGridView1.Font, topLeft, color);
Size s = TextRenderer.MeasureText(beginning, this.dataGridView1.Font);
Point p = new Point(topLeft.X + s.Width, topLeft.Y);
TextRenderer.DrawText(e.Graphics, end, this.dataGridView1.Font, p, SystemColors.WindowText);
}
I did something similar once and ended up putting these characters in their own column.