I am struggling to get a datagrid working nicely for me. I realise there may be other controls that can do what I’m planning but i’m a way down the line with the datagrid so would like to see if this is possible. Essentially I have the following datagrid which is being bound to a SQL connection:
<asp:datagrid ID="dginventory" AutoGenerateColumns="false" runat="server" Width="99.4%" AllowPaging="True" AllowSorting="true" PageSize="20" OnPageIndexChanged="ChangePage" OnSortCommand="SortGrid" OnEditCommand="dginventory_oneditcommand" OnDeleteCommand="dginventory_ondeletecommand" >
<HeaderStyle CssClass="datagridheader"/>
<AlternatingItemStyle CssClass="datagridalternating"/>
<ItemStyle cssClass="datagriditem"/>
<Columns>
<asp:BoundColumn DataField="PurchaseYear" ItemStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="center" HeaderText="YOP" ItemStyle-Width="4%" SortExpression="PurchaseYear ASC" />
<asp:BoundColumn DataField="PurchaseDate" ItemStyle-HorizontalAlign="Center" HeaderText="Purchased" ItemStyle-Width="7%" DataFormatString="{0:d}" SortExpression="PurchaseDate ASC" />
<asp:BoundColumn DataField="Number" HeaderText="Number" ItemStyle-Width="5%" SortExpression="Number ASC" />
<asp:BoundColumn DataField="Theme" HeaderText="Theme" ItemStyle-Width="10%" SortExpression="Theme ASC" />
<asp:BoundColumn DataField="Name" HeaderText="Name" ItemStyle-Width="30%" SortExpression="Name ASC" />
<asp:BoundColumn DataField="RRP" ItemStyle-HorizontalAlign="Left" HeaderText="RRP" ItemStyle-Width="4%" DataFormatString="{0:C}" />
<asp:BoundColumn DataField="PurchasePrice" ItemStyle-HorizontalAlign="Left" HeaderText="Cost" ItemStyle-Width="4%" DataFormatString="{0:C}" />
<asp:BoundColumn DataField="Discount" ItemStyle-HorizontalAlign="Left" HeaderText="Dis." ItemStyle-Width="4%" DataFormatString="{0:P1}" />
<asp:BoundColumn DataField="ReleaseDate" ItemStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="center" HeaderText="Rel. Date" ItemStyle-Width="7%" DataFormatString="{0:d}" SortExpression="ReleaseDate ASC" />
<asp:BoundColumn DataField="RetireDate" ItemStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="center" HeaderText="Ret. Date" ItemStyle-Width="7%" DataFormatString="{0:d}" SortExpression="RetireDate ASC" />
<asp:BoundColumn DataField="Retailer" HeaderText="Retailer" ItemStyle-Width="10%" SortExpression="Retailer ASC" />
<asp:BoundColumn DataField="StorageLocation" ItemStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="center" HeaderText="Box" ItemStyle-Width="3%" SortExpression="StorageLocation ASC" />
<asp:TemplateColumn HeaderText="" ItemStyle-HorizontalAlign="left" ItemStyle-VerticalAlign="Middle" HeaderStyle-HorizontalAlign="center" ItemStyle-Width="2%">
<ItemTemplate>
<asp:ImageButton src="Images/edit-alt-regular-24.png" ID="btneditset" alt="Edit" class="imagebutton" CommandName="Edit" runat="server" />
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="" ItemStyle-HorizontalAlign="left" ItemStyle-VerticalAlign="Middle" HeaderStyle-HorizontalAlign="center" ItemStyle-Width="2%">
<ItemTemplate>
<asp:ImageButton src="Images/trash-regular-24.png" ID="btndeleteset" class="imagebutton" CommandName="Delete" runat="server"/>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
<PagerStyle NextPageText="Next -->" Font-Bold="True" PrevPageText="&lt-- Prev" HorizontalAlign="Center" ForeColor="White" BackColor="Red" Mode="NumericPages" />
</asp:datagrid>
As you can see I have two template columns, each containing an image. One for delete and one for Edit. I cannot seem to catch the click events of these image buttons no matter what I try. If I replace one of them with a ButtonColumn then that works fine however that means that I can’t use an image.
In the code behind I’ve setup these:
Sub dginventory_oneditcommand(ByVal sender As Object, ByVal e As DataGridCommandEventArgs)
lblfilters.Text = "edit"
End Sub
Sub dginventory_ondeletecommand(ByVal sender As Object, ByVal e As DataGridCommandEventArgs)
lblfilters.Text = "delete"
End Sub
Neither one of them seems to actually catch anything. I’ve also tried using onitemcommand which again doesn’t seem to fire. I did try adding an onclick to the two imagebuttons too but again no joy.
Hopefully I’ve described this well enough. I am using vb.net for the code behind in case that wasn’t clear.
Here’s hoping….
2
Answers
thank you for such an amazing response. I did try something similar to that, at one point yesterday, without much success. I have implemented your recommendation but it still doesn't seem to fire the event, or catch the right thing. I've only updated the delete button for now:
Here is the code behind. For now it should just update a label on the form so that I can see something happening. I have also put a breakpoint on this the "lblfilters.Text =" line but that's not breaking either.
Although it wasn't in your example I also dropped in the causevalidation = false to make sure I wasn't being hampered but that.
Any ideas? Sorry
Ok, the easiest way to do this when dropping in a button, ImageButton, or even a combo box for a row?
Ignore the row command approach, and use a regular click event for the given control.
The only "trick" here is that because the control is nested (in a repeater, Listview, GridView, DataGrid etc.), then you don’t have a property sheet for the given control, and thus can’t use the property sheet (or a double click) on the control to create the click event.
However, you are 100% free to add, use and enjoy a click event by typing in markup directly. (and intel-sense will still help you).
I should also point out that a DataGrid is the perhaps the oldest control, and in fact you often not see DataGrid in the tool box.
So, I suggest in most cases to use a GridView. (they are very similar).
And if you "grid" of data has more then a few custom controls, then I suggest using a ListView, as it is far more markup friendly. No worry, and using DataGrid is still ok despite being an older control.
So, so say we have a simple DataGrid like this:
(and note the 2 image buttons).
So, then this:
And code to load the grid looks like this:
And the result is this:
Ok, so let’s add a delete click event to the image delete button in above.
So, it looks like this from the editor:
So, as above shows, we are allowed and can with ease use standard click events (or other events) for that given control. This means VERY little reason exists to bother with and trying to use the row command. And bonus is we thus have a separate click event for each control and they are not all mumbled up into one event with a bunch of case statements.
In the code behind, we can then pick up the row information like this:
In above, I show how you get the current row (DataGridItem).
In above, I show how you get the database PK value.
In above, I show how you get the row index.
Note the use of "naming" container. This is supported for ALL data bound controls, and returns the current row item.
So, when I click on a given row button, then I have this in the output/debug window:
So, you are free to use regular click events for controls placed in a GridView, ListView, DataGrid etc.
And the above advice also extends to say dropping in a combo box, or other controls. Their events can also be used, but you have to "type in" the event setting directly into the markup since the control is nested, and thus no property sheet is available.
And for completeness, it fast becomes tiring to type code over and over to pull a data table with supplied SQL, so I have some helper routines I used in above, and use throughout the application.