How can I force the redisplay of the value of the UpDown box?
I have an application that has a number of UpDown boxes for setting values of a configuration file before loading the file onto an embedded device. I can load a configuration from the device and display the values in the appropriate UpDown boxes.
However, if I delete the contents of an UpDown box and then update it's value, the value of the updown box does not get redrawn unless I increment or decrement the value with the integrated buttons.
Steps to take to reproduce:
Start App.
Delete value from UpDown box so it displays nothing
Change the UpDownBox's .Value, there is still no value displayed.
Increment or decrement the UpDown box with the buttons, the correctly changed value is displayed.
I have tried the following with no change.:
fenceNumberUpDown.Value = config.getFenceNumber();
fenceNumberUpDown.Refresh();
fenceNumberUpDown.Update();
fenceNumberUpDown.ResetText();
fenceNumberUpDown.Select();
fenceNumberUpDown.Hide();
fenceNumberUpDown.Show();
fenceNumberUpDown.Invalidate();
Here's a couple of workarounds I was able to come up with or may give you some other ideas to solve the problem.
Workaround #1: Call UpButton() before setting the value.
this.numericUpDown1.UpButton();
this.numericUpDown1.Value = 20;
Workaround #2: Extend NumericUpDown and overide the Value property.
public class NumericUpDownNew : NumericUpDown
{
public new decimal Value
{
get { return base.Value; }
set
{
string text = "";
if(this.ThousandsSeparator)
text = ((decimal)value).ToString("n" + this.DecimalPlaces);
else
text = ((decimal)value).ToString("g" + this.DecimalPlaces);
Controls[1].Text = text;
base.Value = value;
}
}
}
I just faced this same issue, and I found another workaround which some users may prefer:
numUpDown.Text = " ";
numUpDown.Value = 12.34m;
Just setting the Text (a hidden property which IntelliSense doesn't suggest but exists though) to a non-numeric value (but not empty) forces the control to render the new value. If you don't assign Value any number afterwards, it will restore the last valid value the control had.
Related
I have a problem to reset a dropdownlist is c# I have hiden and showed dropdown's depending on a value in the first selection dropdown box my code did work but i remembered you can type in a combobox and changed it to dropdownlist in visual studio and after that nope not working anymore. so basically i don't want the items to be removed from list it must just be at the starting "empty value" like it was when program loaded here is the code that worked before the change
if(serviceFault_cb.Text == "Report Fault")
{
serviceType_cb.Text = "";
serviceType_cb.Hide();
serviceType_lb.Hide();
faultMain1_lb.Show();
faultMain1_cb.Show();
}
else if (serviceFault_cb.Text == "Service and Faults")
{
serviceType_cb.Show();
serviceType_lb.Show();
faultMain1_lb.Show();
faultMain1_cb.Show();
}
else
{
serviceType_cb.Show();
serviceType_lb.Show();
faultMain1_cb.Text = "";
faultMain1_lb.Hide();
faultMain1_cb.Hide();
}
a basic if statement to hide and show combobox's just need the value to clear when box is hidden and loaded again
Add an empty item into each combobox that would work as a deselected value.
Add it before you add the actual items, then you can deselect a value by doing
serviceType_cb.SelectedIndex = 0;
panel_erviceType.Show();
Also I'd suggest using a panel to encapsulate the combobox with it's corresponding label to hide them simultaneously.
I'm trying to create a simple listbox with ObjectListView (WinForm, C#). The goal is to have a single value (a double) and a check box.
I want to be able to edit the double value by Single Click, so here are the relevant lines of code from my MyWindow.Designer.cs file (i've left out the default values for efficiency):
this.olvDepths = new BrightIdeasSoftware.ObjectListView();
this.olvColumn1 = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
...
this.olvDepths.CellEditActivation = BrightIdeasSoftware.ObjectListView.CellEditActivateMode.SingleClick;
this.olvDepths.CheckBoxes = true;
this.olvDepths.CheckedAspectName = "IsDefault";
this.olvDepths.FullRowSelect = true;
//
// olvColumn1
//
this.olvColumn1.AspectName = "Depth";
this.olvColumn1.Text = "";
this.olvColumn1.IsEditable = true;
I then create a list of my class (ShieldingEntry) and use the olvDepths.SetObjects() with the list. My ShieldingEntry class looks like this:
public class ShieldingEntry
{
public double Depth { get; set; }
public bool IsDefault { get; set; }
}
However, when I click the field, it doesn't go into edit mode. I've also tried the DoubleClick, SingleClickAlways, and F2Only modes and they don't work either.
The Checkbox works fine.
************** I have additional information *********************
I've pulled and build the ObjectListView source, so I could step through it.
I put a breakpoint in the OLV StartCellEdit method and it gets called and appears to setup and select the control appropriately. It just never appears...
As I noted in the comments on the answer below, I've got this control on a tabbed dialog, and if I switch to another tab, then back, the control works fine.
What am I missing?
I've used ObjectListView before, and here is what I had to do:
Handle the CellEditStarting event. This event is raised when the cell goes into edit mode. Since OLV doesn't really have built-in editors, you have to make your own. Then handle the CellEditFinishing event to validate the data before putting it back into your model.
So first, handling the CellEditStarting event:
private void objlv_CellEditStarting(object sender, CellEditEventArgs e)
{
//e.Column.AspectName gives the model column name of the editing column
if (e.Column.AspectName == "DoubleValue")
{
NumericUpDown nud = new NumericUpDown();
nud.MinValue = 0.0;
nud.MaxValue = 1000.0;
nud.Value = (double)e.Value;
e.Control = nud;
}
}
This creates your editing control. If you want to make sure the size is right, you can set the size of the control (in this case a NumericUpDown) to the cell bounds using e.CellBounds from the event object.
This will show the editor when you click in the cell. Then you can handle the editor finished event to validate the data:
private void objlv_CellEditFinishing(object sender, CellEditEventArgs e)
{
if (e.Column.AspectName == "DoubleValue")
{
//Here you can verify data, if the data is wrong, call
if ((double)e.NewValue > 10000.0)
e.Cancel = true;
}
}
I don't think handling it is required, but its good practice to validate data from the user.
The editing control in the CellEditStarting event can be any control, even a user defined one. I've used a lot of user defined controls (like textboxes with browse buttons) in the cell editor.
[Edit]
I uploaded an example here dropbox link that seems to work. Might not be in the exact view as needed, but seems to do the job.
For anyone else with this problem. I had it specifically when trying to edit a 'null' value in a decimal? on the OLV on a tab page. Solution for me was to set UseCustomSelectionColors to 'False'. I didn't look elsewhere to see if it was reported as a bug. Seems like a bug.
Here I'm talking about Windows Forms Application written in C#. Consider a simple model
class Labelled
{
private string label;
public string Label
{
get { return label; }
set
{
if (label != value)
{
string message = String.Format(
"Label changed from {0} to {1}",
label, value
);
MessageBox.Show(message);
label = value;
}
}
}
public Labelled(string label)
{
this.label = label;
}
}
class Model
{
public Labelled SingularLabelled { get; set; }
public List<Labelled> ListedLabelled { get; set; }
public Model()
{
SingularLabelled = new Labelled("Singular");
ListedLabelled = new List<Labelled>();
for (int i = 1; i <= 10; ++i)
ListedLabelled.Add(new Labelled("Listed " + i.ToString()));
}
}
We have a simple class Labelled with string property Label and class Model with member SingularLabelled of type Labelled and ListedLabelled which is a list of Labelled's.
Now I want to display the data to the user. Here is my setup:
The main window has a TextBox for displaying SingularLabelled.Label and a DataRepeater from the Visual Basic PowerPacks to display labels of the elements of ListedLabelled. The ItemTemplate of the DataRepeater consists of just a single TextBox.
Let's focus on one way binding, namely I want the underlying data to be updated when the User changes the contents of a text box. The Label property of the Labelled raises a notification in form of a message box, so I can get to know exactly when the data is being updated. Now the arrows represent bindings. Blue arrows stand for data source and the red ones for data members. An instance of Model is created and bound to the modelBindingSource in the constructor of the main window form.
And here we come to a very important thing. I want the data to be updated immediately in sync with what the User is typing, so I made sure that the data source update modes of the data bindings are set to OnPropertyChanged. The generated code that might be of interest here is
this.singularTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.modelBindingSource, "SingularLabelled.Label", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
this.listedTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.listedLabelledBindingSource, "Label", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
And this is working as expected when typing into the text box of SingularLabelled but the text boxes within DataRepeater trigger the update only when they loose focus. I want them to behave like the singular one. Ideal solution would be to do it using the designer. Does anyone know how to do this?
Above is a sample of the program working. Notice how SingularLabelled's label is updated every character put in and the members of ListedLabelled get the whole edited chunk updated after the corresponding text box looses focus.
We were able to overcome this limitation of DataRepeater by simulating the Tab key.
private void listedTextBox_TextChanged(object sender, EventArgs e)
{
//simulate tab key to force databinding
SendKeys.Send("{TAB}");
SendKeys.Send("+{TAB}");
}
I have following XAML -
<TextBox Text="{Binding Path=NumberOfItems, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />
<Button Command="{Binding Path=StartCommand}">Start</Button>
In ViewModel -
public string this[string columnName]
{
get
{
string result = null;
switch (columnName)
{
case "NumberOfItems":
if (this.NumberOfItems <= 0)
{
result = "Items required";
}
break;
}
return result;
}
}
Whenever, TextBox changes values the trigger works accordingly. But in following cases, It is not working -
When user presses delete button in keyboard after selecting whole text of textbox.
When user deletes the last character present in TextBox.
however ValidatesOnDataError is working.
How can I make it work when TextBox empties?
When user enters any invalid data, TextBox Style changes. I want this to be known in click of Start Button.
How can I make aware the Start button that TextBox has invalid data?
I am guessing you are trying to Bind a property of type integer to the text property of your textbox. Since integers cannot be null, empty string will not work in this case. You can use either nullable integer or you can create your own converter to handle empty string.
When user enters any invalid data, TextBox Style changes. I want this to be known in click of Start Button.
How can I make aware the Start button that TextBox has invalid data?
change your validation code to:
case "NumberOfItems":
if (this.NumberOfItems==null || this.NumberOfItems <= 0)
{
result = "Items required";
}
break;
You can check string.IsNullOrEmpty(this["NumberOfItems"]) within the CanExceuteStartCommand of your StartCommand
I'm using DevExpress.
In my project i have control (textEdit), which EditValue is binded to the property of "int" type.
Problem is that control allow to enter only numbers.
My task is: while form is in edit mode, the textEdit should display word "Automatic", and only after safe button press there should be generated number.
Now in edit mode textbox shows "0", is it possible to make it show "Automatic" in case of "0".
there is the property, to which the textBox is binded:
int fEventNr;
public int EventNr {
get { return fEventNr; }
set { SetPropertyValue<int>("EventNr", ref fEventNr, value); }
}
everything works except that it shows "0" and I don't know how to make him show "automatic"
maybe someone has any ideas?
This is a solution to your problem:
textEdit1.Properties.CustomDisplayText += new Properties_CustomDisplayText;
void Properties_CustomDisplayText(object sender, DevExpress.XtraEditors.Controls.CustomDisplayTextEventArgs e)
{
if (yourCondition)
e.DisplayText = "Automatic";
}
txtEdit.Properties.NullText = "Automatic";
txtEdit.EditValue = null;
Consider changing public int EventNr to public int? EventNr so that you can be sure that the user HAS NOT supplied any value if the EditValue is null and you should generate it "Automatic"aly :)
I believe it's a bad practice to consider 0 as [value not set]. That is the reason why they invented the null.
On the properties panel go to Properties -> Mask . Set "MaskType" to RegEx and set "EditMask" to \d*. If you don't want integers to begin with zero(s) then set "EditMask" to [1-9]+\d* instead.
Alternatively you can do it by code :
this.textEditIntegersOnly.Properties.Mask.EditMask = "[1-9]+\\d*";
this.textEditIntegersOnly.Properties.Mask.MaskType = DevExpress.XtraEditors.Mask.MaskType.RegEx;