When I use a numbericupdown object with thousandsseperator set to true it only updates the text to display the commas correctly when it loses focus. Is there a way to force it to refresh each time the value is changed?
You would need to do an event.
As we know, the thounsandseperator is triggered by focus we can simply call it as we type.
private void numericUpDown1_KeyUp(object sender, KeyEventArgs e)
{
numericUpDown1.Focus();
//Edit:
numericUpDown1.Select(desiredPosition,0)
}
So as the user type, we give the box the it focus back which is a hack to recall the thousandsseperator formatting.
Note: Problems with hacks are wierd situations which calls for more hacks... e.g: Cursor sets back to the front of the text... you would need another hack to fix it.
Experiment with the other events to find the one that fits your case.
Edit: Btw, if you do want to go even further with this ...
Keep Track of the cursor.
Put back the cursor at the right position when keyup is called.
Setting the cursor position in numericUpDown control
To format the text value in your control you'd need a call to ParseEditText() which is protected but can be accessed from a class which inherits NumericUpDown. The problem is after your call the cursor will move before the first character. In order to control the position of the cursor you need access to the SelectionStart property which NumericUpDown don't expose. NumericUpDown still has a field named upDownEdit of type UpDownEdit. The UpDownEdit class although internal inherits from TextBox and behave much like one. So a solution would be to inherit from NumericUpDown and use reflection to get/set the value of upDownEdit.SelectionStart. Here is something you can work on:
public class NumericUpDownExt : NumericUpDown
{
private static FieldInfo upDownEditField;
private static PropertyInfo selectionStartProperty;
private static PropertyInfo selectionLengthProperty;
static NumericUpDownExt()
{
upDownEditField = (typeof(UpDownBase)).GetField("upDownEdit", BindingFlags.Instance | BindingFlags.NonPublic);
Type upDownEditType = upDownEditField.FieldType;
selectionStartProperty = upDownEditType.GetProperty("SelectionStart");
selectionLengthProperty = upDownEditType.GetProperty("SelectionLength");
}
public NumericUpDownExt() : base()
{
}
public int SelectionStart
{
get
{
return Convert.ToInt32(selectionStartProperty.GetValue(upDownEditField.GetValue(this), null));
}
set
{
if (value >= 0)
{
selectionStartProperty.SetValue(upDownEditField.GetValue(this), value, null);
}
}
}
public int SelectionLength
{
get
{
return Convert.ToInt32(selectionLengthProperty.GetValue(upDownEditField.GetValue(this), null));
}
set
{
selectionLengthProperty.SetValue(upDownEditField.GetValue(this), value, null);
}
}
protected override void OnTextChanged(EventArgs e)
{
int pos = SelectionStart;
string textBefore = this.Text;
ParseEditText();
string textAfter = this.Text;
pos += textAfter.Length - textBefore.Length;
SelectionStart = pos;
base.OnTextChanged(e);
}
}
Related
I have been given an assignment on C# window form where I get to calculate an input textbox from a user, the user wants to input a value and then presses a radiobutton(square root) then clicks a normal button to get the result. Is it possible to get the result in a textbox (instead of a label)? If so, how do I do that using 'methods' (linking methods to the button_click one)? Also, why do I need to return a parameter value of a method? it doesn't let me execute without returning ;/
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private int square(int A)
{
if (rbSquare.Checked)
{
Math.Sqrt(A);
return Convert.ToInt32(Math.Sqrt(A));
}
else
{
return A;
}
}
private void btncalculate_Click(object sender, EventArgs e)
{
int firstNum = Convert.ToInt32(tbinput.Text);
int squareRoot = square(firstNum);
tbResult.Text = "" + squareRoot;
}
}
}
Is it possible to get the result in a textbox (instead of a label)?
Sure. Set the text property of the text box, just like you would set the label text of a label.
why do I need to return a value from a method?
You said that square returns an int always, but you only return an int if the checkbox is checked. The compiler is reminding you that you need to return an int always in order to fulfill the contract that you promised. What value should you return if the checkbox is not checked?
I have a simple question in asp.net.
I want to know if it is possible to get data from controls in my user control directly . I want to do it without using Session variable,Viewstate ...
EDIT: I now use the method of declaring public variables in the UC.
Here is a part of Page_load from my parent page:
this.plan_action = (UCPlan)Page.LoadControl("~/Association/UCPlan.ascx");
PlaceHolder1.Controls.Add(this.plan_action);
if (this.plan_action.Validate == true)
{
CheckBox1.Checked = true;
//String référence = Session["liste_action"].ToString();
for (int i = 0; i < this.plan_action.List1.Count; i++)
{
Label8.Text += this.plan_action.List1[i].Référence + "/";
//Label8.Text += "/";
}
}
but my variable validate stay to false.
Here is the code where I change the value of the validate variable with it declaration:
private bool validate;
public bool Validate
{
get { return validate; }
set { validate = value; }
}
protected void Button2_Click(object sender, EventArgs e)
{
//myCommand.Connection = myConnection;
//Session["liste_action"] = this.List;
this.Validate = true;
//Response.Redirect("../Risques_folder/AjouterRisque.aspx");
}
Thank you for your help,
Quentin
UPDATE due to new information
You need to learn about the sequence of events in ASP.NET.
The Load of the page happens a long time before the Click handler of Button2 in your UserControl... so the Validate property is always going to be set to false.
You have two obvious options (as I see it)...
Keep the creation of the UserControl in your Page_Load (or preferably, move it to your Page_Init, as this is normally the most appropriate place for it). Then place your check for the Validate property in a Page_PreRender.
Or, create an Event in your UserControl, Raise that event on the click of Button2, and handle the event in the Page.
ANOTHER UPDATE
For the 2nd of the two options above, in your UserControl class have the following...
public delegate void ButtonClickedDelegate(object sender, EventArgs e);
public event ButtonClickedDelegate ButtonClicked;
In the Button2_Click method of the UserControl (after setting the this.Validate = true;) call...
ButtonClickedDelegate(sender, e);
In the Page_Init of the Page, put something like...
ctrl1.ButtonClicked += new UCPlan.ButtonClickedDelegate(ctrl1_ButtonClicked);
And then have a new method called something like
void ctrl1_ButtonClicked(object sender, EventArgs e)
{
if (ctrl1.Validate)
{
...
}
}
Remember, as you control the delegate you can pass whatever information you want, including an entire class. So instead of calling the Validate property, create a new instance of the class you want, and pass that as a delegate parameter.
You can find more information on delegates and events on MSDN.
ORIGINAL ANSWER
Unless I've missed something, this is a very simple ASP.NET concept...
You can create properties and/or methods.
For example, as a property...
public string MyProperty
{
get { return "My Property Value"; }
}
Or as a method
public string MyMethod()
{
return "My Method Value";
}
If you're talking about passing the values between the UserControl and the ASP.NET Page that contains it, then in your Page, you can simply call the property or method. If your control was called (for example) myCtrl, then you can something like...
string prop = myCtrl.MyProperty;
string meth = myCtrl.MyMethod();
(On the back of the great comment from AHMED EL-HAROUNY)
If you're talking about passing the values to the client side page, then you can use the same properties / methods directly in the HTML markup. However, in this case, the properties / method can be declared as protected rather than public
For instance, to display the value...
<%=MyProperty%>
Or
<%=MyMethod()%>
Or if you're going to use the value in javascript, something like...
var myProp = "<%=MyProperty%>";
Yes That is possible, But exposing the controls in the UserControl as Public.
I have something to do under a button click (add values to listbox) only if a particular string changes from its previous value. How do I manage this? Below is a sample of my code:
private void button6_Click(object sender, EventArgs e)
{
string x = //some varying value I get from other parts of my program
listBox1.Items.Clear();
listBox1.Items.Add(x + /*other things*/);
}
I can at times have same value for string x from previous value when clicking button6. In such cases I don't want listBox1 to add the item (string x). How to add to listbox only when value of string changes? There's no way to predetermine string x. It gets value when program is running.
Note: adding values to listBox1 every single time and later deleting the duplicates wont work in my program.
Have you considered keeping a copy of the old string value around in a private field, and simply comparing the new value to the old value to see if they match?
For example:
// holds a copy of the previous value for comparison purposes
private string oldString = string.Empty;
private void button6_Click(object sender, EventArgs e)
{
// Get the new string value
string newString = //some varying value I get from other parts of my program
// Compare the old string to the new one
if (oldString != newString)
{
// The string values are different, so update the ListBox
listBox1.Items.Clear();
listBox1.Items.Add(x + /*other things*/);
}
// Save the new value back into the temporary variable
oldString = newString;
}
Edit: As the other answers suggest, there are certainly other, more complicated solutions, like encapsulating all access to the string value in a property, or wrapping the string in a custom class. Some of these alternatives have the potential to be "cleaner", more object-oriented approaches. But they're all more complicated than simply saving the previous value in a field. It's up to you to decide whether your specific use case merits the complicated solution, or a simpler one. Think about long-term maintainability, not what's easier for you to implement right now.
string last = string.Empty;
private void button6_Click(object sender, EventArgs e)
{
string x = //some varying value I get from other parts of my program
if(x!=last)
{
listBox1.Items.Clear();
listBox1.Items.Add(x + /*other things*/);
last = x;
}
}
If this string is super important and gets passed around alot, maybe you should wrap it in a class. The class can hold the string value as a property, but also keep track of when it has changed.
public class StringValue
{
private bool _changed;
public string StrValue{get; set{ _changed = true;}
public bool Changed{get;set;}
}
this is rudimentery of course
I'm not sure I understand completely, but it sounds like you should be using a property to set String x;
string _x = string.Empty;
public string X
{
set
{
if(value != this._x)
{
DoFancyListBoxWork();
this._x = value;
}
}
get
{
return this._x;
}
}
If this is web application, store your last value into session variable. If this is windows application, store it at a class level variable or in singleton class and use this last value for comparison with new value.
On the page load add the current value to viewstate and at the button click check the current value is equal to the value in the view state. If both are equal we can say that the value is not changed.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ViewState["CurrentValue"] = Your Value;
}
}
protected void btnSubmit_click(object sender, EventArgs e)
{
if (NewValue== ViewState["CurrentValue"].ToString())
{
lblmsg.Text = "value is not changed..";
return;
}
else
lblmsg.Text = "value is changed..";
}
You can check the detailed article in this link.
Check Control Value is changed or not
First, I'd like to ask you to check most of the other answers. They are more complete, in that they treat more global issues of tracking the changes of a variable.
Now, I'm assuming, from reading the snippet of code you provided, that you need to track if a string was changed by the user. So, in other words, you probably have a TextBox or other kind of control through which the user can change that value. This is where you should focus your attention: just consume the TextChanged event.
If, however, I'm mistaken and your string comes from any other kind of external source, either use the wrapper class suggested by #Ryan Bennett or, if you are using .Net 4, use a dynamic container, which raises a PropertyChanged event whenever any property is changed.
i make a function that uses a control as a parameter, and i use the control's property 'enable'.
the problem is that the control have Enable=false and inside the function it's true,
any ideas why?
protected override void OnPaint(PaintEventArgs pevent)
{
try
{
...
Shared.DrawTextByAlignment(pevent.Graphics, this, this.TextAlign);
}
catch (Exception ex) { MessageBox.Show("Button:OnPaint\n" + ex.Message);
}
static public void DrawTextByAlignment(Graphics g, Control myControl, ContentAlignment TextAlign)
{
...
Brush myBrush;
if (myControl.Enabled) myBrush = new SolidBrush(myControl.ForeColor);
else myBrush = Brushes.Gray;
...
}
When passing a control, you are almost universally talking about a class / object-instance, so all you are passing is the reference to the control - the control itself is identical.
One possible cause of this is an incorrect check:
if(ctrl.Enabled = true) { // spot the assignment!
DoSomething(ctrl);
}
which should be:
if(ctrl.Enabled == true) {
DoSomething(ctrl);
}
or just:
if(ctrl.Enabled) {
DoSomething(ctrl);
}
but the compiler would tell you that in a warning...
Assignment in conditional expression is always constant; did you mean to use == instead of = ?
This leaves only a few options:
the Enabled has genuinely changed, perhaps due to a state-change such as moving it in a control tree
the Enabled property defies all sanity and changes upon inspection
the Enabled property is thread-specific and you are talking to it from multiple threads
or, there is something else going on in your code that your question doesn't tell us, but the source might
I rather expect it to be the last option...
I think you might be need Visible property instead on enabled property.
Because Enable = false the control does not create any changes
If you derive a class from Control and override the Enabled property using the new keyword, your function will still access Control.Enabled. Change the signature to
static public void DrawTextByAlignment(..., MyControl myControl, ...)
I have an event handler for the TextBox.TextChanged event on a form of mine. In order to support undo, I'd like to figure out exactly what has changed in the TextBox, so that I can undo the change if the user asks for it. (I know the builtin textbox supports undo, but I'd like to have a single undo stack for the whole application)
Is there a reasonable way to do that? If not, is there a better way of supporting such an undo feature?
EDIT: Something like the following seems to work -- are there any better ideas? (It's times like this that I really wish .NET had something like the STL's std::mismatch algorithm...
class TextModification
{
private string _OldValue;
public string OldValue
{
get
{
return _OldValue;
}
}
private string _NewValue;
public string NewValue
{
get
{
return _NewValue;
}
}
private int _Position;
public int Position
{
get
{
return _Position;
}
}
public TextModification(string oldValue, string newValue, int position)
{
_OldValue = oldValue;
_NewValue = newValue;
_Position = position;
}
public void RevertTextbox(System.Windows.Forms.TextBox tb)
{
tb.Text = tb.Text.Substring(0, Position) + OldValue + tb.Text.Substring(Position + NewValue.Length);
}
}
private Stack<TextModification> changes = new Stack<TextModification>();
private string OldTBText = "";
private bool undoing = false;
private void Undoit()
{
if (changes.Count == 0)
return;
undoing = true;
changes.Pop().RevertTextbox(tbFilter);
OldTBText = tbFilter.Text;
undoing = false;
}
private void UpdateUndoStatus(TextBox caller)
{
int changeStartLocation = 0;
int changeEndTBLocation = caller.Text.Length;
int changeEndOldLocation = OldTBText.Length;
while (changeStartLocation < Math.Min(changeEndOldLocation, changeEndTBLocation) &&
caller.Text[changeStartLocation] == OldTBText[changeStartLocation])
changeStartLocation++;
while (changeEndTBLocation > 1 && changeEndOldLocation > 1 &&
caller.Text[changeEndTBLocation-1] == OldTBText[changeEndOldLocation-1])
{
changeEndTBLocation--;
changeEndOldLocation--;
}
changes.Push(new TextModification(
OldTBText.Substring(changeStartLocation, changeEndOldLocation - changeStartLocation),
caller.Text.Substring(changeStartLocation, changeEndTBLocation - changeStartLocation),
changeStartLocation));
OldTBText = caller.Text;
}
private void tbFilter_TextChanged(object sender, EventArgs e)
{
if (!undoing)
UpdateUndoStatus((TextBox)sender);
}
You might be better off using the Enter and Leave events instead. When entering, store the current text in a class variable, then when leaving compare the new text to the old.
Yes, don't tie it directly to the textbox. Your forms' state should be in some model object somewhere that isn't directly tied to the form (MVC is one way to do this, MVVM is another). By decoupling them like that, you can compare the new textbox value to the current model value whenever a change request comes in.
Actually, all I can think of is having some kind of collection where you store different string versions (so you can undo many times, not just once).
I would store the reference to TextBox's collections in TextBox.Tag, so it is straightforward to store/use it.
Last but not least, you update your collection of strings during the event TextChange. With no much work, you can maintain a full history, gettinjg the previous value from your own structure.
This is probably overkill for what you're trying to accomplish, but CSLA support n-level undo. CSLA is a great business objects framework written by Rocky Lhotka. The business objects handle the undo history and it flows to the UI through data binding.
Switching your app to use CSLA would be a big commitment, but another option would be to look through the freely available source code to see how he implemented it.
I am actually making an own Syntax-Highlight-System so I also need to know the changed text.
My solution is to watch for an enter or space or an depositioning of the cursor.
As WinForms provide the Keydown event I used the KeyEventArguments (e) and converted them to a char.
After that I storage the char into a string like :
string i="";
i+=convertedToChar; // convertedToChar = kc.ConvertToString(e.KeyData)
And as soon as there is a enter or space or depositioning - "event" I delete the string.
Result:
If a user enters a few chars and hit space I am able to read the last chars (till the last space).
An advantage would be the fact that you can use any delimiter char for that (as soon as they are storaged and provided by e.KeyCode)
However I hope that this is a solution for everybody watching this after 9years :D.
It´s never too late.