OnItemCommand Doesn't Work on Telerik Grid - c#

I'm trying to create a Telerik grid where one of the columns contain a button that clicking it performs a certain action.
This is my definition of the grid in ASP:
<sq:Grid runat="server" CssClass="Master" ID="ReportGrid" DataSourceID="WorkPackageDS"
CellSpacing="0" GridLines="None" PageSize="100" AllowSorting="True" OnItemCommand="CancelWorkPackage_OnItemCommand"
AllowCustomPaging="True" AutoGenerateColumns="False" EnableViewState="False">
And this is the button I added:
<sq:GridTemplateColumn FilterImageToolTip="סינון" HeaderText="ביטול חבילת עבודה" UniqueName="btnCancelWO">
<ItemTemplate>
<asp:ImageButton runat="server" ID="btnCancel" ImageUrl="~/Shared Resources/imaes/tasksButton.png"
CommandName="CancelWO" CssClass="GridImageButton">
</asp:ImageButton>
</ItemTemplate>
</sq:GridTemplateColumn>
The "sq" is just something in my company, but it means a Telerik object.
This is my C# code of the function:
public void CancelWorkPackage_OnItemCommand(object sender, GridCommandEventArgs e)
{
if (e.CommandName == "CancelWO")
{
if (e.Item is GridDataItem)
{
GridDataItem gridDataItem = e.Item as GridDataItem;
string WFGUI = gridDataItem.FindControl("GUI").ToString();
int WorkflowInstanceId = Int32.Parse(gridDataItem.FindControl("fldIWfId").ToString());
RoadsManager.Instance.CancelWorkPackage(WFGUI, WorkflowInstanceId);
RoadsManager.Instance.LogCancellation(new[] { WorkflowInstanceId }, CurrentActivityId, CurrentUserId);
SignManager.Instance.DownloadPermitsFromSSRS(WorkflowInstanceId, WorkflowAPI.Instance.GetWorkflowVariable<object>(WorkflowInstanceId, "ReportName").ToString());
ShowAlert("חבילת עבודה ואישורים בוטלו בהצלחה", 400, 150, "הודעה חשובה");
}
}
}
I added breakpoint in the beginning of the C# function (on the if) and the program doesn't even enter the function.
What am I doing wrong?
Can anyone give me a tip what to change?
Thank you in advance

I changed the entire column from GridTemplateColumn to GridButtonColumn and now it works fine.

Related

Missing vertical border to the left of Header in asp:Gridview

I have a asp:gridview with a header and paging but I'm wonderig that the vertical border to the left of the header is missing as shown in the image below (it is to the left of the string "Postnummer"):
As it can be seen it is only this little part of the gridview that is missing - every other border works correctly.
The declaration of the gridview is as follows:
<asp:GridView ID="gvPost" AutoGenerateColumns="False"
EnableViewState="true"
EmptyDataText="Listen er tom!" runat="server" CellPadding="4"
ForeColor="#333333" Font-Size="Small" AutoPostBack="True"
CssClass="Gridview"
DataKeyNames="Postnummer"
DataSourceID="odsRecords"
AllowPaging="true"
OnPageIndexChanging="gvPost_PageIndexChanging"
AllowSorting="True"
PageSize="50" GridLines="Both"
ShowFooter="false" OnRowDataBound="gvPost_RowDataBound">
So what can I do to show this part of the vertical border?
I hope that someone can give me a hint.
Thanks in advance
Michael
you should do it in the background like below
protected void gvPost_RowDataBound(object sender, GridViewRowEventArgs e)
{
foreach (TableCell tc in e.Row.Cells)
{
tc.Attributes["style"] = "border-color: #000000";
}
}
The solution is as follows:
protected void gvPost_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
e.Row.Cells[0].Style.Add("border-left-color", "#000000");
}
}

How can I get access to the button from code behind

How can I get access to the button from code behind using id "btnAutocomplete"?
<asp:GridView DataKeyNames="AutocompleteSchoolChild_Child" Width="1500px" CssClass="table table-bordered" OnDataBound="GridAutocomplete_OnDataBound"
ID="GridAutocomplete" runat="server" AutoGenerateColumns="false" AllowPaging="true" DataSourceID="sqlAutocomplete" Visible="true" PageSize="10"
OnSelectedIndexChanged="GridAutocomplete_OnSelectedIndexChanged">
<Columns>
<asp:TemplateField ItemStyle-HorizontalAlign="Center" ItemStyle-width="80px">
<ItemTemplate runat="server">
<asp:Button CssClass="btn btn-default" runat="server" ID="btnAutocomplete" Text="Зачислить" CommandName="Select"/>
</ItemTemplate>
</asp:TemplateField>
...
I assume that you want to change button text in currently selected row, so that you need to use FindControl with GridViewRow instance & cast it to a Button control:
protected void GridAutocomplete_OnSelectedIndexChanged(object sender, EventArgs e)
{
GridViewRow row = GridAutocomplete.SelectedRow;
Button btnAutocomplete = (Button)row.FindControl("btnAutocomplete");
btnAutocomplete.Text = "Insert"; // example to use button property
}
If you want to change button text in all GridView rows, you can use foreach loop together with GridViewRow instances on the same event handler:
foreach (GridViewRow row in GridAutocomplete.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
Button btnAutocomplete = (Button)row.FindControl("btnAutocomplete");
btnAutocomplete.Text = "Insert"; // example to use button text property
}
}
If you're not sure that FindControl cast works properly, change all direct casts to as operator & use null checking like this:
GridViewRow row = (sender as GridView).NamingContainer as GridViewRow;
Button btnAutocomplete = row.FindControl("btnAutocomplete") as Button;
if (btnAutocomplete != null)
{
btnAutocomplete.Text = "Insert"; // example to use button text property
}
NB: The goal here is getting GridViewRow instance first before accessing button control inside TemplateField, so that SelectedRow is a proper way to get currently selected row.
Why don't you simply use GetElementById javascript method
document.getElementById("btnAutocomplete").innherHTML("");
Or jQuery:
("#btnAutocomplete").val = "";
As you've asked how to use this, I suggest that you add the code below after your HTML or your aspx layout code which you wrote in your question.
<script type="text/javascript">
//this function runs when the webpage is loaded
$(document).ready(function ()
{
document.getElementById("btnAutocomplete").innherHTML("whatever you want here");
//OR
("#btnAutocomplete").attr("style","whatever style html you want here");
});
//OR declare a private function which you can call through a click event
function buttonchange()
{
("#btnAutocomplete").val = "whatever value you want to give it";
}
</script>
You can assign the call event of the private function to some html element, for example:
<button type="button" class="btn" onclick="buttonchange()">Button changer</button>
i think you can define OnRowCommand for your gridview and define command name for your button,see this:
<asp:GridView DataKeyNames="AutocompleteSchoolChild_Child" Width="1500px" CssClass="table table-bordered" OnDataBound="GridAutocomplete_OnDataBound"
ID="GridAutocomplete" runat="server" AutoGenerateColumns="false" AllowPaging="true" DataSourceID="sqlAutocomplete" Visible="true" PageSize="10"
OnSelectedIndexChanged="GridAutocomplete_OnSelectedIndexChanged"
OnRowCommand="GridAutocomplete_RowCommand">
<Columns>
<asp:TemplateField ItemStyle-HorizontalAlign="Center" ItemStyle-width="80px">
<ItemTemplate runat="server">
<asp:Button CssClass="btn btn-default" runat="server" ID="btnAutocomplete" Text="Зачислить" CommandName="Select"/>
</ItemTemplate>
</asp:TemplateField>
and in code behind:
protected void grdSms_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName.ToLower() == "select")
{
//do something
}
}

How to get selected item from Dropdown in GridView?

I have a GridView. Whenever I'm clicking on the LinkButton after selecting the Dropdown value, I'm getting only the first item of the Dropdown.
I need to show the selected value in TextBox. How can i get the desired value ?
This is my pseudo code:
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" EnableModelValidation="True"
OnRowDataBound="GridView1_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="ID">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%#Eval("ID")%>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Count">
<ItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server" EnableViewState="true" AutoPostBack="false">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Button">
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" OnClick="LinkButton1_Click">LinkButton</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And the code behind:
protected void Page_Load(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.Columns.Add("ID", typeof(string));
dt.Columns.Add("Count", typeof(string));
dt.Rows.Add("A", "5");
dt.Rows.Add("B", "8");
dt.Rows.Add("C", "4");
dt.Rows.Add("D", "7");
dt.Rows.Add("E", "9");
GridView1.DataSource = dt;
GridView1.DataBind();
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddl = (DropDownList)e.Row.FindControl("DropDownList1");
ddl.Items.Clear();
int count = Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "Count").ToString());
List<string> list = new List<string>();
for (int i = 1; i <= count; i++)
{
list.Add(i.ToString());
}
ddl.DataSource = list;
ddl.DataBind();
}
}
protected void LinkButton1_Click(object sender, EventArgs e)
{
GridViewRow grdrow = (GridViewRow)((LinkButton)sender).NamingContainer;
DropDownList ddl = (DropDownList)GridView1.Rows[grdrow.RowIndex].FindControl("DropDownList1");
TextBox1.Text = ddl.SelectedValue.ToString();
}
Thanks in advance...
I'm going to guess that you should implement INotifyProperty change with the databinding. This way every change will be recorded including those made after first change in the drop down box. see ~ http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx
Since you are dynamically creating and binding the Dropdownlist, it would not have loaded at the point your click event is executed. For you to use bound properties (the selectedValue property in this case), the control must already be loaded and it's viewstate info parsed and set by the control.
The databinding event that creates the dropdownlist runs after pre-render. See http://msdn.microsoft.com/en-us/library/ms178472%28v=vs.85%29.aspx for details on the page lifecycle.
To do what you are asking requires very close attention to the page life cycle. Try moving the code that sets the textbox to the GridView1_RowDataBound method. For this to work though, your control must be rendered with the same properties everytime (that way the event's on it are wired up correctly and the selectedValue property is set correctly).
Another alternative is to handle events on the textbox or dropdownlist itself. You would again have to pay attention to the properties and lifecycle of the control.
ASP.Net Forms uses the SmartUI pattern and IMHO this is the single greatest knock against this pattern.
Ok, try this
protected void LinkButton1_Click(object sender, EventArgs e)
{
LinkButton lnkBtn = (LinkButton)sender;
GridViewRow row = (GridViewRow)lnkBtn.NamingContainer;
DropDownList ddl= (DropDownList)row.FindControl("DropDownList1");
TextBox1.Text = ddl.SelectedValue.ToString();
}

RadGrid Get Selected Row Index from Item Template Button

I am working on a project using Telerik controls. I'm trying to figure out how to get the selected row index on an ItemTemplate button click event, like in the markup below:
<telerik:RadGrid ID="RadGrid1" runat="server" AllowFilteringByColumn="True"
DataSourceID="cusGrid" GridLines="None" Skin="Default" AllowPaging="True" DataKeyValue="CustomerID"
PageSize="500" AllowMultiRowSelection="True" ShowStatusBar="true" >
<MasterTableView AutoGenerateColumns="False" DataKeyNames="CustomerID" DataSourceID="cusGrid">
<RowIndicatorColumn>
<HeaderStyle Width="20px"></HeaderStyle>
</RowIndicatorColumn>
<ExpandCollapseColumn>
<HeaderStyle Width="20px"></HeaderStyle>
</ExpandCollapseColumn>
<Columns>
<telerik:GridTemplateColumn UniqueName="CheckBoxTemplateColumn">
<ItemTemplate>
<asp:Button runat="server" Text="Select" OnClick="SelRecord" />
</ItemTemplate>
</telerik:GridTemplateColumn>
...
Normally with a GridView I would just do something like:
protected void SelRecord(object sender, EventArgs e)
{
var gRow = (GridViewRow)(sender as Control).Parent.Parent;
var key = string.Empty;
if (gRow != null) { key = gRow.Cells[0].Text; }
}
What is the equivalent with the Telerik control?
Use the CommandArgument, and use OnCommand instead of OnClick to get the row index:
<asp:Button ID="Button1" runat="server" CommandArgument='<%#Container.ItemIndex%>' OnCommand="Button1_Command" ... />
Code-behind:
protected void Button1_Command(object sender, CommandEventArgs e)
{
GridDataItem item = RadGrid1.Items[(int)e.CommandArgument];
}
You can use CommandName="" instead of OnClick.
Also add onitemdatabound="RadGrid1_ItemDataBound" to the main telerik:RadGrid tag.
Then in the code behind:
protected void RadGrid1_ItemDataBound(object sender, GridItemEventArgs e)
{
if (e.Item is GridDataItem)
{
GridDataItem dataItem = e.Item as GridDataItem;
int selectedRowIndex = dataItem.RowIndex;
}
}
Looking through the Telerik documentation, it looks like you want:
var gRow = ((sender as Button).NamingContainer as GridItem).Selected;
You didn't ask about this piece, but I think this code:
if (gRow != null) { key = gRow.Cells[0].Text; }
is asking for trouble.
Although markup and code-behind are always highly coupled, directly referencing individual cells is a code smell if you ask me. I'm guessing that you want to pull "Select" out of the ASP Button in your ItemTemplate.
Can you assign an ID to your Button, and call FindControl("buttonID") to get the data you need? That will help keep your code more maintainable and readable.
<telerik:GridTemplateColumn UniqueName="IndexRow" HeaderText="#">
<ItemTemplate>
<%#Container.ItemIndex + 1%>
</ItemTemplate>
</telerik:GridTemplateColumn>
something like this in Button click event should work
foreach (GridDataItem item in RadGrid1.SelectedItems)
{
GridDataItem item = (GridDataItem)RadGrid1.SelectedItems;
var key = string.Empty;
key = item.ItemIndex;
}

create dynamic grid with drop down

I want to create a dynamic gridview with first row as drop down on clicking edit button. I dont have any idea on how to start. Can you please help. I have gone through some articals and found using the InstantiateIn method we can achieve.
public class CreateItemTemplate : ITemplate
{
//Field to store the ListItemType value
private ListItemType myListItemType;
public CreateItemTemplate(ListItemType item)
{
myListItemType = item;
}
public void InstantiateIn(System.Web.UI.Control container)
{
//Code to create the ItemTemplate and its field.
if (myListItemType == ListItemType.Item)
{
TextBox txtCashCheque = new TextBox();
container.Controls.Add(txtCashCheque);
}
}
}
If you want to display this on a single page, you should not be creating a server control.
Use the grid's TemplateField.
Note: if you are using AutoGenerateColumns = true, just add the column to the grid markup. It will be added first.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="true">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:DropDownList id="someId" runat="server">
<asp:ListItem Text="One" />
<asp:ListItem Text="twO" />
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
you may need to provide more information about what you want to do wth this drop down (does it need a default value?).
Based on your needs, you may be able to do this in markup, or, you may need to use a grid event.
Brian
UPDATE: adding event handler
if you set onrowcreated="GridView1_RowCreated" in the grid
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="true"
onrowcreated="GridView1_RowCreated">
and do this in your code behind:
protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var dropdown = e.Row.FindControl("someId") as DropDownList;
//dropdown.DataSource= <>; bind it
//dropdown.SelectedValue =<>"; / set value how you would
}
}
you can manipulate the drop down ad it gets created.
If it cannot fin the controls look in each cell: e.Row.Cells[[index]].FindControl(""someId"")

Categories

Resources