C# /windows forms: linking trackbar and textfield with a factor - c#

linking a trackbar and a textfield is very easy in windows forms.
it is like this:
textBox.DataBindings.Add("Text", trackBar, "Value");
the problem is, that trackbars only allow for integer values but i want to have floating point values.
so i usually just divide the value by 100, since on the trackbar the value is not directly visible to the user.
but in the textbox it is.
so is it possible to link these two with a factor of 100?
thanks!

The line of code you have adds a Binding object to the text box's DataBindings collection.
The Binding class has events called Format and Parse, which you can use to perform the division (the Format event takes a value from the trackbar and formats it for the text box) and the multiplication (the Parse event takes a value from the text box and scales it for the trackbar).

You can use intermediate variables like below:
public double v{set;get;}
public int v100
{
set { v = value / 100D; }
get { return (int)(v* 100D); }
}
and blind them with Controls.
trackBar.DataBindings.Add(new Binding("Value", PtParams, "v100"));
textBox.DataBindings.Add(new Binding("Text", PtParams, "v"));

Related

NumericUpDown rejects value

I've got issues with NumericUpDown control. When I try to input a value, the control seems to reject it, despite the value being well withing Minimum and Maximum.
numericField.Hexadecimal = true
numericField.Minimum = 0;
numericField.Maximum = decimal.MaxValue;
Now, when I input FFFFFFF, it works fine. But adding another F will make the control automatically change the value to 0 upon losing focus.
What might be the reason?

How to look for a specific amount of digits within texbox textChanged event in C#?

In my Windows Form Application, I want to implement a feature where the user has to fill in the serial number of a product that is when matched with any product in the database, the product must appear in a grid. I want to do so using textbox textChanged event.
I am confused in figuring out that either I must prevent firing the textChanged event before the textbox value matches any value in the database. Is there any way to make the textbox expect a specific amount of text or number (my serial numbers are going to be fixed length - like 10001, 10002, 10003) before running the remaining code for showing product in the grid?
You can use TextLength property of the TextBox to get length of text. For example:
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (textBox1.TextLength < 5)
return;
//Send query to database
}
Note: As it's also mentioned by Jimi in the comments, it's good idea to set MaxLength of TextBox to prevent entering more text.
Consider the use of a [MaskedTextBox][1]. A MaskedTextBox is similar to a standard TextBox, except you define the format of the input text. This can be anything, letters, numbers, dashes, etc.
In your case you accept only input of five digits.
Use the windows forms designer to add a MaskedTextBox, or add one yourself:
this.maskedTextBox1 = new System.Windows.Forms.MaskedTextBox();
this.maskedTextBox1.Location = ...
this.maskedTextBox1.Size = ...
// etc. Advise: let forms designer do this
// accept only input of five digits:
this.Mask = "00000";
The operator sees an indication of the length of the requested input. It is impossible for the operator to type a non-digit. Event when all five digits are entered, but also while typing (TextChanged), so if desired you can implement autocompletion. You can even get notified if operator presses one invalid key, so you can inform the operator about the error

.Net C# WinForm DataGridView - TextBox Cell: what's the best way to update/change from a numeric user input to a specific culture currency?

A. BACKGROUND OF THE QUESTION
I am trying to have a cell in a datagridview to accept a numeric only user input, which I've handled on the Grid's EditingControlShowing event and the textbox cell's KeyPress event. Now, after the user hits enter or leaves the focus from that cell, I would like to update the cell's value to have a decimal separator and the specific culture currency. The following is the flow that I'm trying to explain:
numeric user input on a datagridview cell -> done (NOTE: cell's ValueType == int || double already).
on cell's leave focus, update the cell value to have decimal separator and specific currency symbol from a culture, to display. (The reason to have a specific culture so that if the application is installed on a different machine with different culture, it will stay on that specific culture).
on cell's enter focus or editing, i would like to strip all of that separators and currency symbol and go back to the numeric only user input value.
B. THE QUESTIONS
First of all, is there a way to implement this without using the CellFormatting event? (I would like to prefer to avoid using this event because this event is called so often and I don't want to put burden on the performance already).
I already use the following:
NumberFormatInfo numberFormat = CultureInfo.CreateSpecificCulture("de-DE").NumberFormat;
double d = double.Parse(<value>, numberFormat);
string test = d.ToString(numberFormat);
But, it doesn't really updates the value, what do I miss here?
what's the best way to implement the behavior, for example, is the cellValueChanged event and CellEnter event will be the best events to handle the above behavior? or CellValidated and CellEnter events will be best events?
Basically, I'm confused on which event is the best event to handle the behavior (without being called so often such as CellFormatting event which is called every time the grid is painted or basically every time you touch the grid), and how to enforce the NumberFormatInfo to that string value.
Thanks!
EDIT (15/09/2016): I actually can update the value to what I want, by doing this:
string test = d.ToString("c2", numberFormat);
I thought the numberFormat itself is sufficient to applying the format because it has the information, but I actually have to explicitly specifying the format such as "c2" from above example, and it acts like a "command" which take the information from a "dictionary" which in this case the "numberFormat" (the definition).
So, this is how it works for me:
I added DataGridViewColumn programmatically, so when I create those columns, I setup these properties:
DataGridViewTextBox column = new DataGridViewTextBoxColumn();
...
column.ValueType = typeof(decimal);
column.DefaultCellStyle.Format = "c2";
column.DefaultCellStyle.FormatProvider = CultureInfo.CreateSpecificCulture("de-DE").NumberFormat;
Handle on the DataGridView EditingControlShowing event, to remove the Currency Symbol and to only shows the number only during editing the cell's value:
public void Grid_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
...
if(decimal.TryParse(grid.EditingControl.Text, NumberStyles.Currency, CultureInfo.CreateSpecificCulture("de-DE").NumberFormat, out decimalValue))
{
grid.EditingControl.Text = decimalValue.ToString("#", CultureInfo.CreateSpecificCulture("de-DE").NumberFormat);
}
...
}
Handle on the `CellValidating' event, to make sure the user input value is in proper format (or in numeric only):
public void Grid_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
...
//No need to check/validate the new row
if (gridSender.Rows[e.RowIndex].IsNewRow)
{
return;
}
...
if(!decimal.TryParse(value, NumberStyles.Currency, CultureInfo.CreateSpecificCulture("de-DE").NumberFormat, out result))
{
e.Cancel = true;
}
...
}
NOTE: if you do step #1 above (i.e. "c2" and specifying the FormatProvider), then it will automatically shows the Currency Symbol and the decimal points, every time the user leave focus of the cell of that column. So, the only thing needs to do, is stripping the currency symbol and how to show the value in numeric only by doing step #2. Step #3, is just another validation to make sure the input is numeric.
Example Flow:
users click on the cell and in edit more, it will display 1000
user click on another cell or focus away, it will display $1.000,00
user click on the cell again and in editing, it will display 1000
The above solutions works good enough for me.
Why is having a culture currency symbol such a big deal for you Jay??? Also why are decimal points such a big deal??? Can the program work without these and achieve the same goal??? Would it not be better to determine the culture symbol of the currency at the outset in the program and possibly use it as a variable and append it later to the string?

Asp.net datagrid - format meters to feet

Using asp.net 4.5, I have a gridview bound to a sqlserver table.
I have a column of type float that contains a distance value in meters.
However, I'd like to show the value to the user in feet with ft at the end.
Like: 3.28 ft
Is there an opportunity to do a complex conversion of what the user sees?
Also, if the user types in a value of "3.28 ft" I'd like to convert it into meters and store it into the database. Is this also possible?
If either of these are possible, can you point me in the general direction of how this can be done??
Thanks!
You can use the CellFormatting and CellParsing events to control the difference between what is shown to the user and what the actual underlying data value is. CellFormatting occurs just before the data value is shown and allows you to edit it before it is presented to the user. CellParsing occurs just after the user edits the value and allows you to convert the input value from one or more formats back to the original data type.
MSDN on CellFormatting
MSDN on CellParsing

How to refresh DataGridView cells style

I have this simple piece of code on a windows form containing said DataGridView (dgvStatsTable) :
public void LoadStatsTable(DataTable statsTable)
{
dgvStatsTable.DataSource = statsTable;
var smallFont = new Font(dgvStatsTable.Font.FontFamily, dgvStatsTable.Font.Size * 0.67f);
dgvStatsTable.Rows[0].Cells[0].Style.Font = smallFont;
dgvStatsTable.InvalidateCell(0, 0);
//dgvStatsTable.Invalidate();
dgvStatsTable.Refresh();
}
Once that function has been called, my DataGridView contains the correct data to see.
However, that style change that I wanted is not showing (first cell in top-right corner has to have smaller text).
Why?
Is it because the table is set to a DataSource rather than building rows and columns?
Thanks!
The Solution to the problem was to write a handler for the DataGridView.CellFormatting Event
found in this MSDN article in the Setting Styles Dynamically section.
Here is a very nice answer from MSDN network, it appears that in order to have greater control you will need to override some functions.
http://msdn.microsoft.com/en-us/library/7fb61s43(VS.80).aspx

Categories

Resources