I have a page with a food table, and when I want to add a new food, I have a button of "insert food", which when clicked shows a small div with labels, text-boxes and stuff for insertion, and it changes its text from "insert" to "cancel". Here is the code:
protected void insertFoodBTN_Click(object sender, EventArgs e)
{
if (insertFoodBTN.Text == "Insert Food")
{
nameF.Visible = true;
nameFTB.Visible = true;
priceF.Visible = true;
priceFTB.Visible = true;
... etc ...
addFBTN.Visible = true;
insertDiv.Style["display"] = "block";
insertFoodBTN.Text = "Cancel Insertion";
}
else
{
nameF.Visible = false;
nameFTB.Visible = false;
priceF.Visible = false;
priceFTB.Visible = false;
... etc ...
addFBTN.Visible = false;
insertDiv.Style["display"] = "none";
insertFoodBTN.Text = "Insert Food";
}
}
That works fine
My problem is that when I want to close it back by clicking the same "insert food" button it doesn't even enter the function of that insertButton_Clicked.
Notice - its text is "cancel insertion", but the ID hasn't been changed so it should basically enter.
After enquiring - it turns that the two first text boxes cause that, because when I deleted them the Insert div was gone again, as before.
I don't know why, because I have another text box after them which doesn't prevent hiding the div back.
I don't have a clue why is that. Thanks for helping.
[after clicking "Insert food" for the first time, and the div opens][1]
Instead of using a div try surrounding your form with a Panel.
And instead of one button use two.
protected void insertFoodBTN_Click(object sender, EventArgs e)
{
pnInsert.Visible = true;
cancelFoodBTN.Visible = true;
insertFoodBTN.Visble = false;
}
protected void cancelFoodBTN_Click(object sender, EventArgs e)
{
pnInsert.Visible = false;
cancelFoodBTN.Visible = false;
insertFoodBTN.Visble = true;
}
Since you state in the comments that the validators prevent the form from being submitted, the solution is to enable/disable validation for the button when its role changes:
protected void insertFoodBTN_Click(object sender, EventArgs e)
{
if (insertFoodBTN.Text == "Insert Food")
{
...
insertFoodBTN.Text = "Cancel Insertion";
insertFootBTN.CausesValidation = false; // Cancel button does not require valid data
}
else
{
...
insertFoodBTN.Text = "Insert Food";
insertFootBTN.CausesValidation = true;
}
}
Note: Since the button has two different functions, I would suggest to create two buttons instead, only one of which is visible at a given time. That way, you don't have to "reconfigure" your button every time (which also causes you to duplicate things such as the button text in your ASP.NET markup as well as in your code, violating the DRY principle).
Related
Well, I have this situation, in a program I put a Button whose code is activated with PerformClick (programmatically), that button must be invisible in the interface so I put the value visible=false since the beginning of the program but the action on the event click doesn't perform, but if I put visible = true, the action actually is performed, any ideas of the problem?
private void dataGridView1_DoubleClick(object sender, EventArgs e)
{
if(_datosDe == "Insumos")
{
_btnRecargarInsumos.PerformClick();
}
this.Close();
}
_btnRecargarInsumos: is the button and is actually performed in another Form.
private void btnRecargarInsumos_Click(object sender, EventArgs e)
{
objGeneral.regresaDescripciones(ref dsDescripciones);
cbACDescripcion.DataSource = dsDescripciones.Tables[0];
cbACDescripcion.DisplayMember = "Nombre";
cbACDescripcion.ValueMember = "ID";
cbACDescripcion.SelectedIndex = -1;
cbACDescripcion.Text = "";
}
cbACDescripcion: Combobox which will be "reloaded" with the values of the DataSet: dsDescripciones.
The property visible is false since the beginnig of the program, but I also try to set visible=true and just before the method PerformClick() change it, but is the same.
But if I put visible=true since the beginning it works in that way.
If you click a button that's not visible or not enabled, nothing happens, even if you click it programmatically. Here's a workaround that works for me, although it's a bit of a hack:
_btnRecargarInsumos.SuspendLayout();
_btnRecargarInsumos.Visible = true;
_btnRecargarInsumos.PerformClick();
_btnRecargarInsumos.Visible = false;
_btnRecargarInsumos.ResumeLayout();
Why not just put your code in a separate method?
Example:
private StuffToDoAtClick()
{
objGeneral.regresaDescripciones(ref dsDescripciones);
cbACDescripcion.DataSource = dsDescripciones.Tables[0];
cbACDescripcion.DisplayMember = "Nombre";
cbACDescripcion.ValueMember = "ID";
cbACDescripcion.SelectedIndex = -1;
cbACDescripcion.Text = "";
}
//Your Button.Click() code//
private void btnRecargarInsumos_Click(object sender, EventArgs e)
{
StuffToDoAtClick()
}
//Your Datagridview code//
private void dataGridView1_DoubleClick(object sender, EventArgs e)
{
if(_datosDe == "Insumos")
{
StuffToDoAtClick();
}
this.Close();
}
I have been trying to figure out on disabling the text box when text is entered in the text box. I am able to do this but I have also got another problem which is, lets say you have a text box with some word i.e "Welcome". If I edit that and add more letter on to that i.e "WelcomeSSS" adding SSS then text is enabled. But when I delete "SSS" from that text box, button is still enabled and not DISABLED as the text is the same as it was before editing.
How do I make sure that the text is disabled in this situation?
And also I want to add dialog box when a user click on different button to go to different page without saving the edited content. How do i do this?
Here is my code so far:
private void textbox1_IsChanged(object sender, KeyEventArgs e)
{
//SaveButton.IsEnabled = !string.IsNullOrEmpty(TextBox1.Text);
if (TextBox1.Text.Trim().Length > 0)
{
SaveButton.IsEnabled = true;
}
if (WpfHelpers.Confirmation(resources.QuitWithoutSaving, resources.Changes))
{
}
}
This is using KeyUp event handler in wpf.
If I understood your question correctly...
private void textbox1_IsChanged(object sender, KeyEventArgs e)
{
if (textbox1.Text == "Welcome"){
SaveButton.IsEnabled = false;
}
else{
SaveButton.IsEnabled = true;
}
}
You need a data structure for storing the saved values. E.g. a List of strings. In the following snippet, these values are stored in the SavedTextBoxTexts list.
At first, the SaveButton gets disabled (you can do this in the XAML as well). When SaveButton has been clicked, the textBox1.text value will be stored in the list and the button gets disabled.
When textBox1.text is edited and SaveButton exists (already), the different conditions get checked.
If textBox1.text is already stored in SavedTextBoxTexts or textBox1.text is empty or contains only whitespace characters, SaveButton gets disabled. Otherwise the SaveButton will be enabled.
public partial class MainWindow : Window
{
private List<string> SavedTextBoxTexts = new List<string>();
public MainWindow()
{
InitializeComponent();
// Disable button right from the beginning.
SaveButton.IsEnabled = false;
}
private void textBox1_TextChanged(object sender, TextChangedEventArgs e)
{
// The function may be called, while the window has not been created completely.
// So we have to check, if the button can already be referenced.
if (SaveButton != null)
{
// Check if textBox1 is empty or
// textBox1.text is already in the list of saved strings.
if (String.IsNullOrEmpty(textBox1.Text) ||
textBox1.Text.Trim().Length == 0 ||
SavedTextBoxTexts.IndexOf(textBox1.Text.Trim()) >= 0)
{
// Disable Button
SaveButton.IsEnabled = false;
}
else
{
// If textBox1.text has not been saved already
// or is an empty string or a string of whitespaces,
// enable the SaveButton (again).
SaveButton.IsEnabled = true;
}
}
}
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
// Store the text in textBox1 into the SavedTextBoxTexts list.
SavedTextBoxTexts.Add(textBox1.Text.Trim());
// Disable the SaveButton.
SaveButton.IsEnabled = false;
}
// This is executed, when the other button has been clicked.
// The text in textBox1 will not be saved.
private void AnotherButton_Click(object sender, RoutedEventArgs e)
{
if (WpfHelpers.Confirmation(resources.QuitWithoutSaving, resources.Changes))
{
// Move to other page ...
}
}
}
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...
I have to radio buttons that reveal or hide panels.
protected void RadioButtonList1_SelectedIndexChanged(object sender, EventArgs e)
{
if (RadioButtonList1.SelectedIndex == 0)
{
newPanel.Visible = true;
updatePanel.Visible = false;
}
else if (RadioButtonList1.SelectedIndex == 1)
{
newPanel.Visible = false;
updatePanel.Visible = true;
}
}
Outside of these panels is a drop down list which effects a data source (gridview). The second radio button reveals the panel that holds this data source. The code for changing that happens when a different item selected from the drop down menu is as follows:
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
//change WHERE clause for SQL statement that effects grid view based on drop down menu selection
SqlDataSource4.SelectParameters["userIdSelected"].DefaultValue = userNameDropDown.SelectedItem.Value;
}
This functions correctly and updates changes the data source that is being displayed.
However, if I currently have the first radio button chosen (that reveals a different panel) and then change the name from the drop down list, when I go to the second radio button the panel that opens shows the data source that was previous. It does not correctly reflect the change to the drop down menu.
Edit: I have tried adding the change to the radio button change but I still have the same behavior:
protected void RadioButtonList1_SelectedIndexChanged(object sender, EventArgs e)
{
SqlDataSource4.SelectParameters["userIdSelected"].DefaultValue = userNameDropDown.SelectedItem.Value;
if (RadioButtonList1.SelectedIndex == 0)
{
newPanel.Visible = true;
updatePanel.Visible = false;
}
else if (RadioButtonList1.SelectedIndex == 1)
{
newPanel.Visible = false;
updatePanel.Visible = true;
}
}
I've got a standard TextBox control which I'm trying to have mimic the "soft descriptions" like those found in the title and tags boxes on StackOverflow. Essentially, when the user's focus enters the control, it hides the description ("Username") in this case, and sets alignment and color to be that of a standard text control. When the user leaves the textbox, I want to check if the user actually entered anything, and put the username display back up otherwise.
For example:
private void tbUsername_Enter(object sender, EventArgs e)
{
if (tbUsername.TextAlign == HorizontalAlignment.Center)
{
tbUsername.TextAlign = HorizontalAlignment.Left;
tbUsername.ForeColor = SystemColors.ControlText;
tbUsername.Text = String.Empty;
}
}
private void tbUsername_Leave(object sender, EventArgs e)
{
if (tbUsername.Text == String.Empty)
{
tbUsername.TextAlign = HorizontalAlignment.Center;
tbUsername.ForeColor = SystemColors.InactiveCaption;
tbUsername.Text = "Username";
}
}
Unfortunately, when I setup these events, the user cannot tab out of the username control. The control simply flickers and control returns to the textbox control itself until the user has entered something, skipping over the event body.
If I call this.SelectNextControl() in the event, then the event enters an infinite loop.
Does anybody see what I'm doing wrong?
Looks like another way around it (Using Reflector to see that it does refocus back on the Control if the focus was there to begin with). I think it is a bug, but looks like they were just reusing RecreateHandleCore function to redraw the text. So another way would be to focus off the textbox first, then continue:
private void LeaveEvent(object sender, EventArgs e)
{
if (String.IsNullOrEmpty(tbUsername.Text))
{
tbUsername.Text = USER_NAME;
tbUsername.ForeColor = SystemColors.InactiveCaption;
this.Focus();
tbUsername.TextAlign = HorizontalAlignment.Center;
}
}
Setting the TextAlign property on the TextBox control returns focus back to that control. That seems like a bug.
Here is a quick fix:
tbUsername.Enabled = false;
tbUsername.ForeColor = SystemColors.InactiveCaption;
tbUsername.Text = "Username";
tbUsername.TextAlign = HorizontalAlignment.Center;
tbUsername.Enabled = true;
(although somewhat of a hack around unexpected behavior). Simply disable the control before changing the alignment. Another "fix" would be to keep things aligned left, or to measure how many spaces to insert to simulate centering the text.
Use BeginInvoke
private void tbUsername_Leave(object sender, EventArgs e)
{
BeginInvoke(new MethodInvoker(OnLeave));
}
private void OnLeave()
{
if (tbUsername.Text == String.Empty)
{
tbUsername.TextAlign = HorizontalAlignment.Center;
tbUsername.ForeColor = SystemColors.InactiveCaption;
tbUsername.Text = "Username";
}
}