I'm trying to persist CSS user preference to my database according to which of six buttons is selected by the user.
On order to do this, I am trying to assign an integer value to each button click event; whichever is clicked will pass the corresponding integer as a parameter to my data access object to update the database able.
My method reads such:
protected void SetCSS(object sender, EventArgs e)
{
Users setCss = new Users();
if (IsPostBack)
{
if (sender.ToString() == "Blue")
{
setCss.StylePreference = 0;
}
else if (sender.ToString() == "Khaki")
{
setCss.StylePreference = 1;
}
else if (sender.ToString() == "Night")
{
setCss.StylePreference = 2;
}
else if (sender.ToString() == "Pink")
{
setCss.StylePreference = 3;
}
else if (sender.ToString() == "White")
{
setCss.StylePreference = 4;
}
else if (sender.ToString() == "Yellow")
{
setCss.StylePreference = 5;
}
setCss.UserLoginName = Session["eMail"].ToString(); // current user
setCss.SetStylePreference(setCss.UserLoginName, setCss.StylePreference);
}
In each button's click event:
protected void btnBlue_Click(object sender, EventArgs e)
{
SetCSS(btnBlue, null);
}
protected void btnKhaki_Click(object sender, EventArgs e)
{
SetCSS(btnKhaki, null);
}
etc...
I put a watch on the sender object and, when the Pink button is selected, the value assigned to the sender reads
{Text="Pink"}
However, as I step through the if statement in the SetCSS method, when I come to the
else if (sender.ToString() == "Pink")
the condition is not met and, rather than setting the style preference to 3 as it should, the program passes on to the end of the statement, finishing by always assigning a value of 0 to the property.
What am I doing wrong?
Would really appreciate help...
You need to use sender.Id.ToString()
Calling sender.ToString() on an ASP.NET button will return "System.Web.Ui.Button" or something similar.
Paste the code related to how you setup the button and I'll clarify my answer more, as you could need either Id or Text depending on how you're setting the the name on your button.
Realistically, you can refactor this code to be a lot simpler.
You should map the Click event on all of your buttons to SetCSS(). Having a lot of scattered methods to only wrap the call is useless.
Change the if / else block to check for sender.Text
if (sender.Text.ToString() == "Blue")
{
setCss.StylePreference = 0;
}
and do the same for the rest of the statements.
Related
following Problem
I have a WinForm App where I will set variables, here only string, decimal or int, through User-Input. This happens by entering values in textboxes, or setting values in textboxes with buttons (increasing and decreasing). Also there are two checkbox pairs (2x yes/no). The checkboxes save a string in my needed values as well.
After the value is typed into the textbox, or has been set to the right number, the User presses a save button (one button for each value, in total 6 save buttons). The save-button always makes sure the correct value has been entered beofre saving
Before closing the form, I want to check if all my needed values have been filled and if not, tell the user: hey, you forgot that certain value. How can I accomplish that? In my example I would want to check if Height, Unit and No_of _measure have been filled with a value. I could just trhow it all into a big "if" with logical "or" in it (about 14 values in total), but then I dont get the specific value that is missing, should one be not filled in (to tell the user)
example:
public decimal Height { get; private set; }
public int No_of_measure { get; private set; }
public string Unit { get; private set; }
private void button3_Click(object sender, EventArgs e) //Save the rough heigth
{
if (textBox2.Text == "")
{ MessageBox.Show("No value detected in [Current Height] Window. Please Click Start first!"); }
else
{
Height = Convert.ToDecimal(textBox2.Text);
}
}
private void button5_Click(object sender, EventArgs e) //save no. of measurements
{
if (textBox5.Text == "")
{ MessageBox.Show("Please enter a value"); }
else
{ No_of_measure = Convert.ToInt32(textBox5.Text); }
}
private void checkBox3_CheckedChanged(object sender, EventArgs e) //save Unit mm
{
if (checkBox3.Checked == true)
{
checkBox4.Checked = false;
Unit = "mm";
}
label22.Text = "mm";
label23.Text = "mm";
With regards to how to check for null in multiple properties, a rough way would be to store your values in a Dictionary where you can run a linq query as below.. This would require you to make major changes to your form.
// properties dictionary populate with your values
Dictionary<string,string> _propertiesDictionary = new Dictionary<string, string>();
private bool PropertyChecks()
{
return _propertiesDictionary.Any(x => x.Value == null);
}
You can create a form_closing event method and put any logic you require inside of this, example..
private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (PropertyChecks())
{
MessageBox.Show("Some properties are null");
e.Cancel = true;
}
}
I am fairly new to Visual Studio and C# in general but basically I need to check that the contents of the textbox are valid before proceeding to add the contents to a list with a button.
I am using the following objects:
A TexBox to enter the value
A Validating event linked to the TextBox to validate the data.
A Button to take action
A Click event associated to the button.
The problem is that I cannot check if the values in the box are valid or not and prevent the click event in the button to happen. In other words if the contents are not valid then do not take action.
This is my code.
public partial class mainForm : Form
{
public mainForm()
{
InitializeComponent();
}
private void addButton_Click(object sender, EventArgs e)
{
// I need to check if the content is valid before adding it to the form
ListViewItem item = new ListViewItem(this.nameTextBox.Text);
this.listView1.Items.Add(item);
}
private void nameTextBox_Validating(object sender, CancelEventArgs e)
{
int maxCharacters = 15;
String err = "";
String contents = this.nameTextBox.Text;
if (contents.Length == 0)
{
err = "I am sorry but the name cannot be empty";
e.Cancel = true;
}
else if (!contents.Replace(" ", "").Equals(contents, StringComparison.OrdinalIgnoreCase))
{
err = "I am sorry but the name cannot contain spaces";
e.Cancel = true;
}
else if (contents.Length > 15)
{
err = "I am sorry, but the name cannot have more than " + maxCharacters + " characters";
e.Cancel = true;
}
this.mainFormErrorProvider.SetError(this.nameTextBox, err);
}
}
You are confused about when the "name" text boxes' validation method is called.
See here
When you change the focus by using the keyboard (TAB, SHIFT+TAB, and so on), by calling the Selector SelectNextControl methods, or by setting the ContainerControl.ActiveControl property to the current form, focus events occur in the following order...
So clicking the button has nothing to do with the validation of the text box.
What you need to do is put the validation logic in a separate method, and then call it from both events.
Also, since you're new to C# here are some pointers.
Namespaces, Classes, methods, and properties are supposed to be Pascal Case.
Instead of using a long winded work around like this
!contents.Replace(" ", "").Equals(nameText, StringComparison.OrdinalIgnoreCase)
You could simply use
contents.Contains(" ")
There are tons of useful methods just like that, so in the future you should do more research on what you need before implementing something yourself, especially if it seems like a commonly used technique.
Also, you want to avoid if/else's as much as possible in favour of returning early.
Here's what your class might look with better practice in mind
const int NAME_MAX_CHARACTERS = 15;
public mainForm()
{
InitializeComponent();
}
private void addButton_Click(object sender, EventArgs e)
{
if(!Validate())
{
return;
}
// I need to check if the content is valid before adding it to the form
ListViewItem item = new ListViewItem(this.nameTextBox.Text);
this.listView1.Items.Add(item);
}
private void nameTextBox_Validating(object sender, CancelEventArgs e)
{
e.Cancel = !Validate();
}
private bool Validate()
{
string nameText = nameTextBox.Text;
if(String.IsNullOrEmpty(nameText))
{
this.mainFormErrorProvider.SetError(this.nameTextBox, "I am sorry but the name cannot be empty");
return false;
}
if(nameText.Contains(" "))
{
this.mainFormErrorProvider.SetError(this.nameTextBox, "I am sorry but the name cannot contain spaces");
return false;
}
if (nameText.Length > 15)
{
this.mainFormErrorProvider.SetError(this.nameTextBox, "I am sorry, but the name cannot have more than " + NAME_MAX_CHARACTERS + " characters");
return false;
}
return true;
}
Good day, anyone can help me with this problem... I have a combo box and a textbox. the textbox(txtFruitNo) will check the length of text under Leave event. It is ok. But if I click on the combo box while txtFruitNo is not yet completed. It needs me to complete first the length of txtFruitNo then only I can click the combo box.
I do not want to show the messagebox if I click on the combo box even if the length of the txtFruitNo is not yet completed.
Thanks
private void cmbFruitSelection_SelectedIndexChanged(object sender, EventArgs e)
{
DateTime thetime = DateTime.Now;
String varApple = "App-Red";
String varBanana = "Ban-Yellow";
if (cmbFruitSelection.SelectedItem.ToString() == "Apple")
{
txtFruitNo.Text = varApple.ToString() + thetime.ToString("yyyy");
txtFruitNo.SelectionStart = txtFruitNo.Text.Length;
txtFruitNo.MaxLength = 18;
}
else if (cmbFruitSelection.SelectedItem.ToString() == "Banana")
{
txtFruitNo.Text = varBanana.ToString() + thetime.ToString("yyyy");
txtFruitNo.SelectionStart = txtFruitNo.Text.Length;
txtFruitNo.MaxLength = 17;
}
}
private void txtFruitNo_Leave(object sender, EventArgs e)
{
if (txtFruitNo.TextLength != txtFruitNo.MaxLength)
{
MessageBox.Show("Your fruit number is too short. Please check.");
txtFruitNo.Focus();
}
else
{
// Do something here
}
}
At what point is it important for continuation of the program that the "Fruit Number" is within parameters. If it is not at the time of leaving focus try moving it to a different control for example the "OK" button could run the parameter check and if valid continue if not flag mesage box and return to the textbox
Since your requirement is to only to do the validation and prompt the message box once the user has selected a value from the combo, please do the following;
Introduce a form variable
private bool isComboClicked = false;
Add the below line to cmbFruitSelection_SelectedIndexChanged
isComboClicked = true;
Adding the above line at the beginning of the above event would prompt the length validation message on selection of value from the combo. If you want to prompt message for specific value on the combo move it within the if statements if (comboBox1.SelectedItem.ToString() == "Apple") etc.
Now in txtFruitNo_Leave event enclose the code within the below if condition.
if (isComboClicked)
{
// Your Code
if (txtFruitNo.TextLength != txtFruitNo.MaxLength)
{
MessageBox.Show("Your fruit number is too short. Please check.");
txtFruitNo.Focus();
}
else
{
// Do something here
}
}
As I understand:
You have "validation" on TextBox in Leave eventhandler, which show error message if validation fails.
But if TextBox.Leave event was raised by selecting ComboBox control, then validation must be suppressed.
Create Panel and put there only txtFruitNo and cmbFruitSelection controls.
// Validation function
private bool IsTextBoxValid()
{
return this.txtFruitNo.Length == this.txtFruitNo.maxlength;
}
Then create and hook up Validating eventhandler for Panel where you will validate txtFruitNo
private void Panel_Validating(Object sender, CancelEventArgs e)
{
if(this.IsTextBoxValid() == false)
{
e.Cancel = true;
MessageBox.Show("Your fruit number is too short. Please check.") ;
}
}
Validating will be raised only when focus move outside of the panel.
Using Validating event will prevent changing focus to outside controls automatically if e.Cancel = true
In that case combobox cmbFruitSelection can be focused and user can complete txtFruitNo text by selecting valid value from ComboBox.
I think using of ErrorProvider control will be more friendly for the user, then MessageBox.
Add ErrorProvider control in the Form through designer and add few lines in the code
private void Panel_Validating(Object sender, CancelEventArgs e)
{
if(this.IsTextBoxValid() == false)
{
e.Cancel = true;
this.ErrorProvider1.SetError(txtFruitNo,
"Your fruit number is too short. Please check.");
}
else
{
this.ErrorProvider1.Clear();
}
}
And clear error after valid value was used from ComboBox
private void cmbFruitSelection_SelectedIndexChanged(object sender, EventArgs e)
{
DateTime thetime = DateTime.Now;
String varApple = "App-Red";
String varBanana = "Ban-Yellow";
if (cmbFruitSelection.SelectedItem.ToString() == "Apple")
{
txtFruitNo.Text = varApple.ToString() + thetime.ToString("yyyy");
txtFruitNo.SelectionStart = txtFruitNo.Text.Length;
txtFruitNo.MaxLength = 18;
//Clear error
this.ErrorProvider1.Clear();
}
else if (cmbFruitSelection.SelectedItem.ToString() == "Banana")
{
txtFruitNo.Text = varBanana.ToString() + thetime.ToString("yyyy");
txtFruitNo.SelectionStart = txtFruitNo.Text.Length;
txtFruitNo.MaxLength = 17;
//Clear error
this.ErrorProvider1.Clear();
}
}
I need your help.
I created a file "flick.settings" and a bool variable in it called "prop".
When a user checks one of the checkboxes and hits the button, the code should "remember" that prop's value is true and on the next launch it should appear as checked. So, the value must remain even when I replace .exe file with another copy.
Here's a part of my code:
private void remember_Click(object sender, RoutedEventArgs e)
{
if (this.oneone.IsChecked == true)
{
flick.Default.prop = true;
flick.Default.Save();
}
else if (this.oneone.IsChecked == false)
{
flick.Default.prop = false;
flick.Default.Save();
}
}
And to access the variable:
private void show_Click(object sender, RoutedEventArgs e)
{
if (flick.Default.prop == true)
{
this.oneone.IsChecked = true;
}
else if (flick.Default.prop == false)
{
this.oneone.IsChecked = false;
}
}
But when I change the value in flick.settings and save it, my so called program appears to "remember" that bool value inside of it, not in the flick.settings. So, my question is how can I do it right? Help me, please!
[edit]
calling the follows directly is not possible in my code:
void control_Changed(object sender, EventArgs e)
This function is loop through a Collection of DropDownListBox, and each DropDownListBox has different Select_Change function. Also they are not in the same page, they collection of DropDownListBox is come from different user control of the page.
I saw a lot of solution are simply calling the function that the event should trigger..
But this will not be working on my case.
I have a code that will mapping the data to a collection of dropdownlistbox and select the proper dropdownlistbox item for each dropdownlistbox.
So, is kind of like this:
foreach (Control aControl in aControlCollection){
if (aControl.GetType() == typeof(RadComboBox))
{
bool FoundItem = false;
RadComboBox aComboBox = (aControl as RadComboBox);
foreach (RadComboBoxItem aComboItem in aComboBox.Items)
{
Debug.WriteLine("aComboItem " + aComboItem.Text + " Value" + aComboItem.Value);
if (aComboItem.Value.ToLower() == _dataObject.ToString().ToLower())
{
//aComboBox.SelectedIndex = aComboBox.Items.IndexOf(aComboItem);
aComboItem.Selected = true;
FoundItem = true;
~~~FIRE EVENT HERE~~~~~
//break;
}
else {
aComboItem.Selected = false;
}
}
if (!FoundItem)
{
RadComboBoxItem aComboItem = new RadComboBoxItem();
aComboItem.Value = _dataObject.ToString();
aComboItem.Text = _dataObject.ToString();
aComboBox.Items.Add(aComboItem);
aComboBox.SelectedIndex = aComboBox.Items.IndexOf(aComboItem);
}
}
}
}
Normally in the page, when user select the a first dropdownbox, the 2nd dropdownbox that follows will generate the proper dropdownlist item according to the first dropdownbox (from the first dropdownbox selectindexchange event).
So I wonder if there is anyway I can fire the DropDownListBox programmatically?
Just to make it even more clear, the above function is call by iterates all DropDownListBox on the page, so they can be link into different function.
Combobox_SelectedItem(null, null);
You can forge any arguments you desire into the parameters, if needed.
If you were to use the traditional void control_Changed(object sender, EventArgs e) code...
if (aComboItem.Value.ToLower() == _dataObject.ToString().ToLower())
{
//aComboBox.SelectedIndex = aComboBox.Items.IndexOf(aComboItem);
aComboItem.Selected = true;
FoundItem = true;
control_Changed(aComboItem, new EventArgs());
}
void control_Changed(object sender, EventArgs e) {
// your code here
}