I want to make an activity with few edittext fields and a button which should be disabled until the most important of these fields has been filled. This is the code I am using but the button is staying disabled the whole time:
doneButton implementation
if((isEmpty(inputType)) || (isEmpty(inputAmount)) || (isEmpty(inputSupplier)))
doneButton.Enabled = false;
else
doneButton.Enabled = true;
This is the code for the isEmpty() method, which is checking if the edittext is empty or not:
private Boolean isEmpty(EditText etText) {
return etText.Text.ToString().Length == 0;
}
Thanks in advance ! :)
Why not use the TextChanged event:
EditText input = FindViewById<EditText>(Resource.Id.editText1);
input.TextChanged += input_TextChanged;
and then define the event handler for it?
private void input_TextChanged(object sender, TextChangedEventArgs e)
{
Console.WriteLine("input text changed");
// if text bigger than 0, enable the button, otherwise disable it
}
Much cleaner IMHO.
You will need to add this implementation(your code to check if the button stays disabled) inside the TextWatcher#afterTextChanged method , which you would add as a TextChanged listener. You will need to do this for all the edit texts you think are important.
Something like this:
inputType.addTextChangedListener(new TextWatcher(){
public void afterTextChanged(Editable s) {
if((isEmpty(inputType)) || (isEmpty(inputAmount)) || (isEmpty(inputSupplier)))
doneButton.setEnabled(false);
else
doneButton.setEnabled(true);
}
});
Similar listeners over inputAmount and inputSupplier should do the task.
The question is: On which event did you attach this code?
You can, for example, create a TextWatcher object and attach it to the relevant text fields. Something like:
inputType.addTextChangedListener(watcher);
In this watcher you would do the checks you have written and do:
doneButton.setEnabled(true/false);
I solved it like this:
inputType.AfterTextChanged += new EventHandler<AfterTextChangedEventArgs> (OnTextChange);
inputAmount.AfterTextChanged += new EventHandler<AfterTextChangedEventArgs> (OnTextChange);
inputSupplier.AfterTextChanged += new EventHandler<AfterTextChangedEventArgs> (OnTextChange);
where the OnTextChange() method is this:
public void OnTextChange(object sender, EventArgs e)
{
if((isEmpty(inputType)) || (isEmpty(inputAmount)) || (isEmpty(inputSupplier)))
doneButton.Enabled = false;
else
doneButton.Enabled = true;
}
Related
I am trying to make a button visible = false if a quantity in a text box is less than or equal to 0. The problem I am having is that you have to click the button in order to activate the function.
Here is my code so far
int quantity = int.Parse(textBox33.Text);
if (quantity <= 0)
button13.Visible = false;
if (quantity > 0)
button13.Visible = true;
do I have to disable the visibility of the text box beforehand?
Simply go to the form editor and double click on the textbox. In the code presented to you after double clicking add your code or double click on the form itself if you want the code to be executed whenever the form is loaded.
At first you should encapsulate the code to update the button in a specific method:
private void UpdateButton13()
{
button13.Visible = quantity > 0; // no need for if/else
}
Then you can call this from every event after which the button should be updated. From your comments it seems you want to update that button
at Form load and
when the text in textBox33 has been changed.
So for example:
public class YourForm : Form
{
public YourForm()
{
InitializeComponents();
// register event handlers:
Load += YourForm_Load;
textBox33.TextChanged += textBox33_TextChanged;
}
private void YourForm_Load(object sender, EventArgs e)
{
UpdateButton13();
}
private void textBox33_TextChanged(object sender, EventArgs e)
{
UpdateButton13();
}
private void UpdateButton13()
{
button13.Visible = quantity > 0; // no need for if/else
}
}
Of course you can also create and register the event handlers in the designer window, without having to write the code in the constructor yourself.
The code above may now seem a little redundant (same code in two methods and a one-line method). But I assume that you want to do further things on loading the form and on changing text, and maybe you want to call UpdateButton13 from other parts of your code, too. So encapsulating here is good style (imho) to avoid problems for further development.
go to textbox events and insert the code to textChanged event.
but for better than that you can do digit validation event
private void textBox33_KeyPress(object sender, KeyPressEventArgs e)
{
if (!System.Text.RegularExpressions.Regex.IsMatch(e.KeyChar.ToString(), "[1-9]"))
{
e.Handled = true;
}
}
in that case order can be only positive number
Currently I have it so that when you select the text box it will highlight the text in it but what I want it to do is only do this for the first time that it is selected so that it will not delete the text that the user is typing each time. Here is what I am using to highlight the text:
private void txtName_Focus(object sender, EventArgs e)
{
bool isFirstTime = true;
if (isFirstTime == true){
txtName.SelectionStart = 0;
txtName.SelectionLength = txtName.Text.Length;
}
isFirstTime = false;
}
bool isFirstTime = true; this is your problem. It is being initialized to true every time the focus event is being called. Move bool isFirstTime; to be a member of your class and initialize it to true once in the declaration, constructor or the form load event
Maybe something like this:
bool txtNameWasFocused=false;
private void txtName_Focus(object sender, EventArgs e)
{
if(!txtNameWasFocused){
txtNameWasFocused=true;
txtName.SelectionStart = 0;
txtName.SelectionLength = txtName.Text.Length;
}
}
If you need this in many places, you might think of a derived text box with this special behaviour...
Here is code that i used to populate a look up edit:
Letsap.DAL.PersonDataSet dsPerson = new Letsap.DAL.PersonDataSet();
lookUpEdit3.Properties.DataSource = dsPerson.GetPersonsID();
lookUpEdit3.Properties.ValueMember = "Person_ID";
lookUpEdit3.Properties.DisplayMember = "Person_Name";
lookUpEdit3.EditValue = 0;
But I would like to check if the user selected a value, if they did, it must move on to the next screen.
How do I do the check?
You can do it like this. Assuming you have a button with a click event attached, on which you want to check wheter you want to continue:
private void ButtonClick(object sender, EventArgs e)
{
if (lookUpEdit3.ItemIndex >= 0)
{
// show next screen
}
}
I am using c# winform.
I have 2dimensional array of text boxes I want them to accept only Letters from A-I I've created the method but that works for only one text box.
Here is my code:
textbox[i,j].Validated+=new EventHandler(TextBox_KeyPress);
private void TextBox_KeyPress(object sender, EventArgs e)
{
bool bTest = txtRegExStringIsValid(textbox[1,1].Text.ToString());
ToolTip tip = new ToolTip();
if (bTest == false)
{
tip.Show("Only A-I", textbox[1,1], 2000);
textbox[1,1].Text = " ";
}
}
private bool txtRegExStringIsValid(string textToValidate)
{
Regex TheRegExpression;
string TheTextToValidate;
string TheRegExTest = #"^[A-I ]+$";
TheTextToValidate = textToValidate;
TheRegExpression = new Regex(TheRegExTest);
if (TheRegExpression.IsMatch(TheTextToValidate))
{
return true;
}
else
{
return false;
}
}
Can anyone please guide what should I do make this code work for all text boxes?
if this works for textbox[1,1] you could register your private void TextBox_KeyPress(object sender, EventArgs e) as eventhandler for all your textboxes and instead of textbox[1,1] you could use ((TextBox)sender)
i want text boxes to accept only letters from a-i actually i am trying to make sudoku
There's a much simpler solution than regular expressions, and you don't even need to handle the Validated event to implement it.
In a situation like this, where there are only certain characters that you want to prevent the user from entering, handling the KeyDown event is a much better solution. The user gets immediate feedback that the letter they tried to enter was not accepted. The alternative (the Validating and Validated events) actually wait until the user tries to leave the textbox to rudely alert them that their input was invalid. Especially for a game, this tends to break concentration and isn't particularly user-friendly.
Doing it this way also makes it irrelevant which individual textbox raised the event. Instead, you will handle it the same way for all of the textboxes—by completely ignoring all invalid input.
Here's what I'd do:
First, attach a handler method to your textbox's KeyDown event. You can do this from the Properties window in the designer, or you can do it through code, as you have in the question:
textbox[i,j].KeyDown += TextBox_KeyDown;
Then, you need to put the logic into your event handler method that determines if the key that the user just pressed is in the allowed range (A through I), or outside of it:
private void TextBox_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
// Determine if the keystroke was a letter between A and I
if (e.KeyCode < Keys.A || e.KeyCode > Keys.I)
{
// But allow through the backspace key,
// so they can correct their mistakes!
if (e.KeyCode != Keys.Back)
{
// Now we've caught them! An invalid key was pressed.
// Handle it by beeping at the user, and ignoring the key event.
System.Media.SystemSounds.Beep.Play();
e.SuppressKeyPress = true;
}
}
}
If you want to restrict the user to typing in only one letter, you can add code to handle that in the above method, or you can take an even simpler route and let the textbox control handle it for you automatically. To do that, set the MaxLength property of the textbox to true, either in the designer or through code:
textbox[i,j].MaxLength = true;
Check the text of the sender instead of whatever textbox[1,1] is.
Use the sender parameter of the event handler to identify the textbox responsible for the event.
The first thing that will help you is casting the sender of your event to a TextBox like this:
(Also, as Cody Gray said, this is a TextBox_Validated event, not a KeyPress event so I've renamed it appropriately)
private void TextBox_Validated(object sender, EventArgs e)
{
TextBox tb = sender as TextBox()
if (sender == null)
return;
bool bTest = txtRegExStringIsValid(tb.Text.ToString());
ToolTip tip = new ToolTip();
if (bTest == false) {
tip.Show("Only A-I", tb, 2000);
tb .ext = " ";
}
Next you need to actually get into that code for every textbox. There are two obvious approaches to that, you can either assign the eventhandler to each textbox in the array or you can use a custom textbox which always does this validation and then add that to your array.
Assign eventhandler to textboxes
foreach(var tb in textbox)
{
tb.Validated += new EventHandler(TextBox_KeyPress);
}
Create custom textbox control
Create the custom text box control (Add a user control to the project) and then just use it exactly as you would a normal textbox.
public partial class ValidatingTextBox: TextBox
{
public ValidatingTextBox()
{
InitializeComponent();
}
protected override void OnValidating(CancelEventArgs e)
{
bool bTest = txtRegExStringIsValid(this.Text.ToString());
ToolTip tip = new ToolTip();
if (bTest == false)
{
tip.Show("Only A-I", this, 2000);
this.Text = " ";
}
}
private bool txtRegExStringIsValid(string textToValidate)
{
// Exactly the same validation logic as in the same method on the form
}
}
I have a combobox at the top of a form that loads editable data into fields below. If the user has made changes, but not saved, and tries to select a different option from the combobox, I want to warn them and give them a chance to cancel or save.
I am in need of a "BeforeValueChange" event with a cancelable event argument.
Any advice on how to accomplish?
Save the ComboBox's SelectedIndex when to box if first entered, and then restore it's value when you need to cancel the change.
cbx_Example.Enter += cbx_Example_Enter;
cbx_Example.SelectionChangeCommitted += cbx_Example_SelectionChangeCommitted;
...
private int prevExampleIndex = 0;
private void cbx_Example_Enter(object sender, EventArgs e)
{
prevExampleIndex = cbx_Example.SelectedIndex;
}
private void cbx_Example_SelectionChangeCommitted(object sender, EventArgs e)
{
// some custom flag to determine Edit mode
if (mode == FormModes.EDIT)
{
cbx_Example.SelectedIndex = prevExampleIndex;
}
}
Here is the simplest fix:-
bool isSelectionHandled = true;
void CmbBx_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (isSelectionHandled)
{
MessageBoxResult result = MessageBox.Show("Do you wish to continue selection change?", this.Title, MessageBoxButton.YesNo, MessageBoxImage.Question);
if (result == MessageBoxResult.No)
{
ComboBox combo = (ComboBox)sender;
isSelectionHandled = false;
if (e.RemovedItems.Count > 0)
combo.SelectedItem = e.RemovedItems[0];
return;
}
}
isSelectionHandled = true;
}
Save the current value on the Enter event.
Implement the BeforeValueChange logic in the ValueChanged event, before the actual ValueChanged logic. If the user cancels, set the stored value and don't continue in the method (return).
If you're going to use this system a lot, I'd suggest inheriting ComboBox and implementing your BeforeValuechange event there.
The Validating event can be used for this scenario
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.validating.aspx
You don't get an appropriate event by default. You could cache the previous value and set it back to that if the user wants to cancel.
How about using the Validating / Validated events?
It works well, if the event happening on LostFocus instead of Change is ok with you.
Otherwise, how about
public void Combobox_ValueChanged(object sender, EventArgs e) {
if (!AskUserIfHeIsSureHeWantsToChangeTheValue())
{
// Set previous value
return;
}
// perform rest of onChange code
}
You could use a message filter to intercept clicks and key presses, which would allow you to prevent the combo box's normal behaviour. But I think you'd be better off disabling the combo box when the user makes a change, and require them to either save or revert their changes.
You can't really prevent it, but you can change it back to the old value if certain requirements aren't met:
private SomeObject = selectedSomeObject=null;
private void cbxTemplates_SelectionChangeCommitted(object sender, EventArgs e)
{
if (!(sender is ComboBox cb)) return;
if (!(cb.SelectedItem is SomeObject tem)) return;
if (MessageBox.Show("You sure?", "??.",
MessageBoxButtons.OKCancel) != DialogResult.OK)
cb.SelectedItem = selectedSomeObject;
else
{
selectedSomeObject = tem;
}
}