Setting selected value does not trigger SelectedIndexChanged - c#

I have a situation where I need the SelectedIndexChanged to fire when I programatically select an item. Here is what I am doing.
I load a dropdownlist from the database on FormLoad and I am setting the value of the drop down based on information passed in the query string like this:
if (Request.QueryString["nat"] != null)
{
ddlTriggers.ClearSelection();
ddlTriggers.Items.FindByValue(
Request.QueryString["nat"].ToString()).Selected = true;
}
This does work correctly in that it takes the id from the querystring and matches it up to a particular item in the drop down. The issue is that just by setting .selected=true does not fire the selectedIndexChanged event. I am trying to set some labels when the selected index is changed.
Some suggestions showed manually calling selectedIndexChanged like this:
ddlCommonTasks_SelectedIndexChanged(ddlTriggers, EventArgs.Empty);
but then that resets the selectedIndex and shows me the label for the 1st item in the drop down which of course doesnt help me any.
Any suggestions.

The problem is that you are changing the selected index on post back or on page load at server. The event will not fire. What you can do is to take stuff in SelectedIndexChanged handler and refactor it into separate method which can be called whenever you update value like:
ddlCommonTasks_SelectedIndexChanged(object sender, EventArgs e)
{
var ddl = sender as DropDownList;
PerformIndexChangedAction(ddl);
}
private void PerformIndexChangedAction(DropDownList ddl)
{
lblTest.Text=ddl.SelectedItem.Text;
}
Modify the code as follows:
var nat = Request.QueryString["nat"];
if (!String.IsNullOrWhitespace(nat))
{
ddlTriggers.ClearSelection();
ddlTriggers.Items.FindByValue(nat).Selected = true;
PerformIndexChangedAction(ddlTriggers);
}

If I'm right in assuming that you have registered a handler for the selectedIndexChanged event, you could simply call the same function that you registered as a handler for your event.
If you've registered your handler like this:
$( ".target" ).change(function() {
alert( "Handler for .change() called." );
});
You could instead define your function elsewhere, and pass that:
function handler() {
alert( "Handler for .change() called." );
}
$(".target").change(handler);
Now, in your existing code just call your handler function:
if (Request.QueryString["nat"] != null)
{
ddlTriggers.ClearSelection();
ddlTriggers.Items.FindByValue(Request.QueryString["nat"].ToString()).Selected = true;
handler();
}

Related

Cannot Select List View Item Twice

I am having an issue with selecting list view items twice in a row. So when I select one item it loads another list. This is not a problem but when I click back to go back to the previous list view I am no longer able to click the same list view item.
I have done some reading and there seems to be an idea of 'de-selecting' the list view item at some point in the code so being able to select the same item again.
The selection is done using the MVVM model so the code that handles the selection etc.
// bound to list items on front end, reacts to tap on each item
// and loads route information for the route that is selected
RouteInfo _selected_item;
public RouteInfo RouteLabelSelected
{
get { return _selected_item; }
set
{
if (Equals(value, _selected_item)) return;
_selected_item = value;
OnPropertyChanged(nameof(RouteLabelSelected));
OpenRoutePage(_selected_item.ID);
}
}
The OpenRoutePage method simply opens the next list view, as I said this works fine.
I have attached some images to better illustrate the problem.
Any help would be appreciated, forgive the artwork.
in your ItemSelected event handler, you need to set SelectedItem = null
protected void ItemSelected(object source, ItemSelectedEventArgs args) {
// do whatever actions on selected item here
// then reset SelectedItem
((ListView)source).SelectedItem = null;
}
You can create to different event handlers to solve the issue, namely ItemTapped and ItemSelected event handlers. The ItemSelected event is triggered first on clicked/tapped and then it triggers the ItemTapped event. On first tap/click on a listview item, the ItemTapped event is triggered twice after triggering the ItemSelected event. To overcome this issue, you can attach both event handlers and simply set/clear a boolean property.
Example:
private bool _isSelected;
private void ListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
_isSelected = true;
}
private void ListView_ItemTapped(object sender, ItemTappedEventArgs e)
{
if(!_isSelected)
{
//do work here
}
_isSelected = false;
}
Here, first the ItemSelected event is triggered and the variable _isSelected is set. Then the ItemTapped event is triggered twice. The condition in the ItemTapped event prevents the user code from executing in the first call and then allows the code execution in the second call.

Using sender to determine what button is pressed in ListView

I have a ListView that has Update and Cancel buttons. Both of these buttons have a CommandName of Cancel, so they fire the same ListView event handler (ListView_ItemCanceling).
Inside this event handle I execute my stored procedures. The issue I am having is since both buttons fire the same event handler they both update. Even if there are no changes being made.
I would like to try to determine the button that has fired the event at the start of the event handler (possibly using sender?), but I cannot figure out how to do this.
This is what I was currently trying to do in the ListView_ItemCancelling event handler:
Button newButton = (Button)sender;
if(newButton.Text == "Cancel")
{
Console.Write("this worked");
}
When I execute this code I get an error message telling me that I cannot convert the sender object from ListView object to a Button object.
Any help will be greatly appreciated!
You can define to command names for each button to detect the which one is click for example:
define the first as "Cancel1" and the other "Cancel2"
and in the code you can check like that:
if(CommandName == "Cancel1")
{
// do some thing
}
else if(CommandName == "Cancel2")
{
// do other staff
}
or if both at doing the same job but you need to determine the sender
if(CommandName == "Cancel1" || CommandName == "Cancel2")
{
// do some thing common
}
if(CommandName == "Cancel1")
{
// do some thing if button 1 clicked
}
if(CommandName == "Cancel2")
{
// do some thing if button 2 clicked
}
I came to the answer with help from #paqogomez. He suggested I use the ItemCommand event handler for the ListView to get the button that is being clicked for the listview.
Inside the ItemCommand event handler I checked them command argument and used the appropriate code thereafter.
protected void LV_Tickets_ItemCommand(object sender, ListViewCommandEventArgs e)
{
if(e.CommandName == "Update")
{
//code here
}
}
The sender seems to be your ListView, not Button. Try using Button_OnClick event instead of ListView_ItemCancelling.
Or try doing some reseach on ListView_ItemCancelling, such as using ListViewCancelEventArgs e parameter, maybe it can help you in this situation. You can read more about it on MSDN.

Hiding datagridviews bug

I have a windows form with a panel on the left, which consists purely of radiobuttons, and a tabcontrol in the middle, with multiple tab pages within it. Each of these individual tabpages have a series of datagridviews within it, which are shown and hidden depending on which radio button you check.
I accomplish this effect by having each of the radiobuttons on the left assigned a CheckChanged event, which loops through all of the controls within the tabpagecontrol.SelectedTab, and calls .Show() on the corresponding datagridview and calls .Hide() on the rest so that only one datagridview is visible at one time.
My problem occurs when i try to programmatically check one of these RadioButtons. Lets say in Method X, I write RadioButtonA.checked = true. This triggers the usual CheckedChange event handling, which loops through all the datagridviews on the currently selected tabpage and calls .Hide() on everything except the one datagridview form that the radiobutton is supposed to bring up and calls .Show() instead. However, on one of these .Hide() calls on the datagridview, it ends up triggering the RadioButtonA.CheckedChange event AGAIN for a second time. When i look at the sender argument passed to the function, it shows that the sender is the RadioButton i just programmatically clicked on.
I am adding these datagridviews programmatically and can confirm that there are no eventhandlers assigned whatsoever to them. Can anyone help me determine what is causing this additional event to get triggered? Thanks.
For obnoxious change events that trickle through and upset other event handlers on my forms, I've found the only solution is to add a small boolean value:
bool radioIng;
void MyMethod() {
radioIng = true;
try {
radioButton1.Checked = true;
// etc.
} finally {
radioIng = false;
}
}
void radioButton_EventHandler(object sender, EventArgs e) {
if (radioIng) return;
// rest of code here
}
EDIT:
Alternately, you could just remove all of your event handlers and reconnect them later:
void MyMethod() {
try {
radioButton1.CheckChanged -= radioButton_EventHandler;
radioButton2.CheckChanged -= radioButton_EventHandler;
radioButton3.CheckChanged -= radioButton_EventHandler;
// execute your code
radioButton1.Checked = true;
} finally {
radioButton1.CheckedChanged += new EventHandler(radioButton_EventHandler);
radioButton2.CheckedChanged += new EventHandler(radioButton_EventHandler);
radioButton3.CheckedChanged += new EventHandler(radioButton_EventHandler);
}
}
void radioButton_EventHandler(object sender, EventArgs e) {
if (sender == radioButton1) {
// code here to handle
} else if (sender == radioButton2) {
// code here to handle
} else if (sender == radioButton3) {
// code here to handle
}
}

C# asp.net Button_Click event handler not working

I have a webusercontrol with a few controls on it like some labels,a textbox and eventually a button. The purpose of this control is to add it to my main page in a placeholder every time I click on the button on the webusercontrol.
This is the code behind my button on my webcontrol
protected void btnCriteriaToevoegen_Click(object sender, EventArgs e)
{
//New eventhandler == all of the eventhandlers of all the objects who have subscribed to the event.
EventHandler eventhandler = ButtonDoorgaan;
ButtonOpslaanEvent mijnevent = new ButtonOpslaanEvent();
//Basic variables I will give with my costum event(ButtonOpslaanEvent)
mijnevent.Naam = txtCriteriumNaam.Text;
mijnevent.Score = Convert.ToInt16(DdlCriteriumScoreSchaal.SelectedValue);
int weging = Convert.ToInt16(DdlCriteriumWeging.SelectedValue) - 1;
mijnevent.Weging = Convert.ToInt16(weging);
//If the eventhandler is not null, for every object that has an eventhandler, execute it.
if(eventhandler!=null)
eventhandler(sender, mijnevent);
}
The eventhandler that need to be executed when the event is fired is defined in my main page like this :
private void critlijn_ButtonDoorgaan(object sender, EventArgs e)
{
ButtonOpslaanEvent eigenevent = (ButtonOpslaanEvent)e;
IEnumerator<Domein> domeinenumerator = domeinen.GetEnumerator();
while (domeinenumerator.MoveNext())
{
if (domeinenumerator.Current.DomeinNaam.Equals(lijstdomeinitemgeselecteerd))
{
Criterium nieuwcriterium = new Criterium();
nieuwcriterium.CriteriumNaam = eigenevent.Naam;
nieuwcriterium.CriteriumScore = Convert.ToString(eigenevent.Score);
nieuwcriterium.CriteriumWeging = Convert.ToString(eigenevent.Weging);
domeinenumerator.Current.Criteriums.Add(nieuwcriterium);
}
}
btnCriteriaToevoegen_Click(sender, e);
}
The btnCriteriaToevoegen_Click event fires and then calls this method(addCriteriaButton()), which will add the button onto the placeholder in my main page:
private void addCriteriaButton()
{
Criterialijn criterialijn = (Criterialijn)LoadControl("~/Criterialijn.ascx");
//Add eventhandlers to control
criterialijn.ButtonDoorgaan += new EventHandler(critlijn_ButtonDoorgaan);
criterialijn.Aangevinkt += new EventHandler(critlijn_Aangevinkt);
//Every control on the page except this one, not enabled
IEnumerator<Criterialijn> criterialijnenumerator = criteriacontrols.GetEnumerator();
while (criterialijnenumerator.MoveNext())
{
criterialijnenumerator.Current.Enabled = false;
}
//Add it to a list of webusercontrols that are currently on screen
criteriacontrols.Add(criterialijn);
criterialijn.Enabled = true;
//Add to placeholder
plhCriteria.Controls.Add(criterialijn);
}
So when all this is said and done, and I run my program, he adds the control to my placeholder, but when I click on the button, he does not add a new control to my placeholder, and just clears my placeholder for some reason. Normally everything should be fine, but I have tried to see if he actually fires the event when you click on the button, and he does not. I have tried to give you a sample of my code, because the code of the whole page is quite big and that would not help you at all. Any ideas why he is not firing the event of the button?
So when your button that you dynamically added posts back, a new page instance is created and that button no longer exists (since you only added it on the previous button click), it has not been recreated.
You must re-create dynamic controls on each postback
Remeber, a new instance of the Page class is created for each postback, any previously created controls, event handlers will not exists in the new instance unless you explicitly re-create them.
I assume these Criteria are some sort of tree structure the user can navigate through (and hopefully arriving at the end somewhere ?).
About btnCriteriaToevoegen_Click:
Why are you defining an event inside a method?
In critlijn_ButtonDoorgaan and addCriteriaButton:
Instead of using an enumerator, just use
foreach(var control in criteriacontrols)
control.Enabled = false;
So yeah, fair to say it's still not quite comprehensable, but it least I tried right? :)
EDIT
ok, then I have this question:
The eventhandler that need to be
executed when the event is fired is
defined in my main page like this :
How sure are you that, when you do
EventHandler eventhandler = ButtonDoorgaan;
the variable "eventhandler" gets all eventhandlers attached to ButtonDoorgaan ?
EDIT 2 (the return)
See Richard Friend's answer; your control is not there anymore

C# checkbox eventhandler

private void CheckBox_CheckedChanged(object sender, EventArgs e)
{
CheckBox chk = (CheckBox)sender;
SetValuesInDB( System.Security.Principal.WindowsIdentity.GetCurrent().Name,
DateTime.Today.Date);
}
Now I want to setvalues of my id and current date in database only if I directly clicked on the checkbox.
I dont want to update those values in Database if some other event triggers this event handler.
For eg: while loading everytime the checkbox gets checked but the database value for this checkbox is unchecked.
so, everytime this event handler is triggered and database value is updated.
How do I take care of it?
Use the CheckBox.Click event instead. It gets fired if either the user clicks on the checkbox or uses Space to toggle the checkbox.
I'm not really sure what you want to do.
If you want the value in the database and userinterface to be always up to date you might try DataBindings...
internal class MyDataSource {
public bool MyBooleanValue {
get { return ReadValueFromDB("MyUser", "MyBool"); }
set { SaveValueToDB("MyUser", value); }
}
}
...
internal class MyControl {
internal MyControl() {
dataSource = new MyDataSource();
InitializeComponents();
myCheckbox.DataBindings.Add(
"Checked", dataSource, "MyBooleanValue"
);
}
private MyDataSource dataSource;
}
otherwise you might wish to write the value only in the database when the user finishes an operation. Such as closing event handler of a form or okButton click event handler.

Categories

Resources