DevExpress: How to create click event handler? - c#

In my app I have a table with some rows. When I press on a '+' next to row, I need to expand it and display another table. How can I add an event handler to code for this '+'? When I press twice on it, I create event handler for click event for all row and I need it only for a '+' button.
This is what it generates:
private void GridCandidates_Click(object sender, EventArgs e)
{
}
This is how I added '+':
[NotMapped]
public List<CandidateStatusLog> CandidateStatusesLog { get; set; }

Most of the events related to the GridControl are actually fired by the view, not the control. For instance, in this case you can handle the GridView's MasterRowExpanding event which is fired as the [+] is clicked and a detail table is about to be displayed.
If you want to dynamically change the details view at runtime, I would suggest reviewing the Load Details Dynamically by Handling Events documentation as well.
The GridControl should automatically be able to generate a detail view if the parent object has a collection property such as a List like you're doing. See the Binding to Objects with Collection Properties for information about this.

Related

master-detail datagridviews : RowValidating wrong behavior when moving focus from detail record to a master record which is not its parent

in my WinForms app. i have master-detail DataGridViews. i have attached a RowValidating event handler to my detail grid to make some validation and calculations.
RowValidating fires whenever a detail record loses focus.
the problem is:
when i set focus on a detail record (for editing or whatever) , and then move focus to master grid by clicking on a record that is NOT the parent of THAT detail record, this is what happens:
first : RowValidating event for that detail record is fired, which is logical (because it lost focus).
then : RowValidating event for its parent record is fired, which is logical, too (because we moved focus to a new parent) .
and then : RowValiding event for detail record is fired AGAIN !!! RowIndex is the same index of the detail record which previously lost focus, BUT the actual details that are present in the detail grid now are details of the NEW parent (which we clicked on)! THIS IS NOT LOGICAL.
i have tried other events (CellLeave, RowLeave) and they act the same :
detail events are fired first for the detail row which lost focus,
then master events are fired for its parent,
then detail events are fired AGAIN, but for details of the new parent and RowIndex of the old detail record ...
WHY are detail events are fired twice? and why are they using RowIndex of the previous detail record ?
P.S. i downloaded a master-detail DGV demo, and tried the same events, and similar things happened.
DEMO:
http://www.codeproject.com/Articles/42569/Three-Master-Details-Related-Grids-on-the-Same-For
for some reseason, when i click on master grid, after all master validation is done, detail RowValidating is executed, and then detail RowEnter is executed (even though i am not clicking on detail).. so, since detail is entered, RowValidating fires before detail RowEnter. old details are supposed to be validated since we are entering new details, that's why the RowIndex is the index of old detail row, but unfortunately old details are already removed from detail grid before RowValidating is executed on them, so validation is "accidentally" applied on new details.
to solve this i added the following :
private void detailGrid_RowValidating(object sender , DataGridViewCellCancelEventARgs e)
{
string current_parent_row_id = masterGrid.CurrentRow.Cells["id"].Value.ToString();
string validated_parent_row_id = detailGrid.Rows[0].Cells["id"].Value.ToString();
if (current_parent_row_id != validated_parent_row_id) return;
// validation goes next ...
}

Tab Control Events

Is there a predefined event for Tab Controls, or maybe something custom I can develop, that will allow me to execute some logic on a control I've removed from that Tab Control's Control Collection, before it ACTUALLY gets removed from the tab control.
Context :
I have a tab control with tab pages. These tab pages load documents related to entries in a reference grid. Each time I select a row in the reference grid, a tab page with the corresponding document loaded gets added to my tab control. The Check column for that row in the grid also gets checked.
I want to be able to close a tab page in my tab control and be able to relate this closed tab page to its corresponding entry in the reference grid so i can uncheck that row.
I've tried browsing through all the possible events for tab control and found nothing suitable. The ControlRemoved event fires only AFTER my tabpage has closed and tab focus has automatically shifted to the next tab.... This is causing my controlremoved logic to fail and enter an infinite loop, trying to close ALL the available tabs instead of just this one, and throwing an invalid index exceptions when it's closed the final one.
You need to ensure that when you uncheck the item in your grid programmatically you do not update the tab control. Otherwise you always will run into an infinite loop causing the unwanted behavior.
You can achieve this by using a boolean flag. In the code-example below I haven't used the "real" event-handlers because I have no IDE at hand to test this at the moment, but rather replaced them by simple methods, so get the idea:
private bool suppressTabUpdate = false;
private void HandleGridCheckedOrUncheckedEvent()
{
if (suppressTabUpdate)
return;
// Insert logic here to create or remove the tab pages as required
}
private void HandleTabPageRemovedEvent()
{
suppressTabUpdate = true;
// Uncheck the item in the grid here
suppressTabUpdate = false;
}
I'm not sure if there's an exact event for you're looking for, but I have an alternative approach to propose.
It sounds to me that some of the UI code is too closely tied together. The grid and the tab control should not be talking to each other directly from the event handlers: that's what's causing the infinite loop (the events are "ping-ponging" back and forth).
Instead, I recommend that both the grid and the tab control be managed by another "component" (just a class, or a few methods in the existing form class) and that this component manage opening/closing tabs and modifying rows in the grid.
For example, when the user selects a row in the grid, don't modify the grid directly at all: instead, call a new method that does whatever needs to happen when a row is selected: check a checkbox, open a tab, etc. When a row no longer needs to be selected, don't change any selections directly: instead, call a new method that does whatever needs to happen when a row is not selected: uncheck a checkbox, close a tab, etc.
If you need a reference to your tab BEFORE it gets removed, there is one simple way to do it. Make CustomTabControl that inherits from TabControl and override its OnControlRemoved event.
If you have this:
public class CTabControl:TabControl
{
protected override void OnControlRemoved(ControlEventArgs e)
{
TabPage tp = e.Control as TabPage; // reference to tab page before it gets removed
base.OnControlRemoved(e);// gets removed here
}
}

How to know which generated button was pushed in listbox?

I'm developing a WP7 app and have a listbox with generated buttons all supposed to lead to somewhere specific. I can't figure out how to know which button was pushed at runtime. The list gets generated from a collection of objects with a couple of attributes in each. One of those attributes contain a value that I need to get to be able to know where to send the user.
So my desired process is that the user clicks on an item in the listbox, passing the value of the attribute in the object the button was generated from, to a click handler which sends the user to the right place.
Any suggestions?
I presume your ListBox contains a ItemTemplate which constructs a Button for each of the items bound to your list? if this is the case, within your Click event handler you need to inspect the DataContext of the button that was clicked:
private void Button_Click(object sender, RoutedEventArgs e)
{
Button btn = sender as Button;
var myObject = btn.DataContext;
}
As an aside, if you are using this for navigation, a ListBox will not give you very good performance. See the following blog post for an alternative:
http://www.scottlogic.co.uk/blog/colin/2011/04/a-fast-loading-windows-phone-7-navigationlist-control/
Check the sender property of the OnClick event handler for the click handling.
Alternatively you may want to handle the SelectionChanged event of the ListBox and then query the contents of the SelectedItem.

Click Event in multiple column list view C# windows form

Hey friends I have list view with 3 columns. I need to fire different events on each click in those column header. HOw can i do that? VS provides simple column click event, how can i use it for separate click event for those column headers.
I think you need to investigate the value of the sender parameter you are getting along with the event.

C# how to access the buttons of Telerik RadGrid

I am using Telerik RadGrid, i add a new button in the grid but how can i write an event for this button (Buy) for example when the user press (Buy) it will add this item to his cart with its price in order to calculate his bill.
regards
You need to listen for the ItemCommand event:
<telerik:GridButtonColumn UniqueName="Buy" ButtonType="LinkButton"
Text="Buy" ConfirmText="Add to cart?"
OnItemCommand="rg_ItemCommand" CommandName="AddToBasket" />
In your codebehind
protected void rg_ItemCommand(object sender, GridCommandEventArgs e)
{
if(e.CommandName == "AddToBasket")
{
// Add to basket code here
}
}
You may also need to set the CommandArgument during the ItemCreated or ItemDatabound events, or get it using something like rg.MasterTableView.DataKeyValues[e.Item.Index]["ItemId"].ToString(); after setting ClientDataKeyNames="ItemId" in your MasterTableView settings part in the ascx file (if it is databound).
You need to use the ItemCommandEvent of grid. The ItemCommand event is raised when a button is clicked in the Telerik RadGrid control. This allows you to provide an event-handling method that performs a custom routine whenever this event occurs. Follow the LINK to have more details.
When you create the button you'll want to add an OnClick event to it to handle the click on the button. In this event you'll then add the item to the cart. You'll need to parse the parent row of the button to know which item it is.
Edit:
Since you are using a GridButtonColumn and not adding a button as you stated then this applies instead (from Telerik.com):
This column renderes a button of the
specified ButtonType in each
corresponding cell of the items of
type GridDataItem and
GridEditFormItem. You can use this
buttons to fire command events that
can be handeled in RadGrid.ItemCommand
event handler. This, in combination
with the event bubbling mechanism in
Telerik RadGrid, allows you to create
a column of custom button controls,
such as Add, Remove, Select or Edit
buttons.
So essentially you'll need to use the grids ItemCommand event to handle the button click.

Categories