I have a RadGrid (Gridview) that has the option to edit and insert new items.
Within both those options i have a customvalidator to check for existing values so duplicates cannot be entered. What i am stuck on is the ability to use findcontrol for the textbox that only is shown during EDIT and INSERT.
This works great for INSERT as i call GetInsertItem(), but that throws an error when editing and i am stuck on that. I want to do this outside of the databound and command methods.
protected void cvAccountNumber_ServerValidate(object source, ServerValidateEventArgs args)
{
TextBox txtAccountNumber = (TextBox)RadGrid1.MasterTableView.GetInsertItem().FindControl("txtAccountNumber");
List<GridDataItem> Items = (from item in RadGrid1.Items.Cast<GridDataItem>()
where item["AccountNumberView"].Text == txtAccountNumber.Text
select item).ToList();
args.IsValid = Items.Count() == 0;
}
Here is an image of the edit screen.
ASPX:
Sort By Status: <asp:DropDownList ID="dd_Status" runat="server" Width="150px"
onselectedindexchanged="dd_Status_SelectedIndexChanged"
AutoPostBack="True">
<asp:ListItem Text="All" Value="0" Selected="True"></asp:ListItem>
<asp:ListItem Text="Active" Value="True"></asp:ListItem>
<asp:ListItem Text="Inactive" Value="False"></asp:ListItem>
</asp:DropDownList>
<br /><br />
<telerik:RadGrid ID="RadGrid1" runat="server" Skin="Vista" Width="500px"
GridLines="None" AllowFilteringByColumn="False" AllowSorting="True" OnExportCellFormatting="RadGrid1_ExportCellFormatting" DataSourceID="SqlDataSource1"
AllowAutomaticDeletes="true" AllowAutomaticUpdates="True" AutoGenerateEditColumn="True" AutoGenerateDeleteColumn="true" OnItemCommand="RadGrid1_ItemCommand" >
<MasterTableView AutoGenerateColumns="False" DataKeyNames="ID" DataSourceID="SqlDataSource1" ItemStyle-HorizontalAlign="Left" CommandItemDisplay="TopAndBottom">
<Columns>
<telerik:GridTemplateColumn HeaderText="ID" SortExpression="ID" UniqueName="ID" Visible="false" ReadOnly="true">
<ItemTemplate>
<asp:Label ID="lblIDView" runat="server" Text='<%# Bind("ID") %>'></asp:Label>
</ItemTemplate>
</telerik:GridTemplateColumn>
<telerik:GridTemplateColumn HeaderText="ID" SortExpression="IDEdit" UniqueName="IDEdit" Visible="false">
<ItemTemplate />
<EditItemTemplate>
<asp:Label ID="lblID" runat="server" Text='<%# Bind("ID") %>'></asp:Label>
</EditItemTemplate>
</telerik:GridTemplateColumn>
<telerik:GridBoundColumn DataField="AccountNumber" HeaderText="Sapphire Account Number"
SortExpression="AccountNumber" UniqueName="AccountNumberView" ReadOnly="true" ItemStyle-Width="400">
</telerik:GridBoundColumn>
<telerik:GridTemplateColumn HeaderText="Sapphire Account Number" SortExpression="AccountNumber" UniqueName="AccountNumber" Visible="false">
<ItemTemplate />
<EditItemTemplate>
<asp:Textbox ID="txtAccountNumber" runat="server" Text='<%# Bind("AccountNumber") %>' />
<asp:RequiredFieldValidator ID="rfvAccountNumber" ControlToValidate="txtAccountNumber"
ErrorMessage="Sapphire Account Number is required" runat="server" ForeColor="Red"></asp:RequiredFieldValidator>
<asp:CustomValidator ID="cvAccountNumber" runat="server" ErrorMessage="Sapphire Account Number already exists"
ControlToValidate="txtAccountNumber" ForeColor="Red" OnServerValidate="cvAccountNumber_ServerValidate"></asp:CustomValidator>
</EditItemTemplate>
</telerik:GridTemplateColumn>
<telerik:GridTemplateColumn HeaderText="Active" SortExpression="Active" UniqueName="Active" ItemStyle-Width="100" Visible="false">
<ItemTemplate />
<EditItemTemplate>
<asp:CheckBox ID="cbActive" runat="server" Checked='<%# GenerateBindString(Container.DataItem) %>' />
</EditItemTemplate>
</telerik:GridTemplateColumn>
<telerik:GridTemplateColumn HeaderText="Status" SortExpression="Active" UniqueName="Active" ItemStyle-Width="100">
<ItemTemplate>
<asp:Label ID="lblActive" runat="server" Text='<%# Convert.ToBoolean(GenerateBindString(Container.DataItem)) == true ? "Active" : "Inactive" %>'></asp:Label>
</ItemTemplate>
</telerik:GridTemplateColumn>
</Columns>
</MasterTableView>
<ValidationSettings CommandsToValidate="PerformInsert,Update" />
<ClientSettings>
<Selecting AllowRowSelect="True" />
</ClientSettings>
</telerik:RadGrid>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:LBCust %>"
SelectCommand="SELECT * FROM [LBX_Portal_AccountNumbers] WHERE ([Site] = @Site) AND (Active=@Active OR @Active = '0') ORDER BY AccountNumber"
DeleteCommand="DELETE FROM [LBX_Portal_AccountNumbers] WHERE [ID] = @ID"
InsertCommand="INSERT INTO [LBX_Portal_AccountNumbers] ([AccountNumber], [Site], [Active]) VALUES (@AccountNumber, @Site, @Active)"
UpdateCommand="UPDATE [LBX_Portal_AccountNumbers] SET [AccountNumber] = @AccountNumber, [Active] = @Active WHERE [ID] = @ID">
<SelectParameters>
<asp:ControlParameter ControlID="dd_Status" Name="Active"
PropertyName="SelectedValue" Type="String" />
</SelectParameters>
<DeleteParameters>
<asp:Parameter Name="ID" Type="Int32" />
</DeleteParameters>
<InsertParameters>
<asp:Parameter Name="AccountNumber" Type="String" />
<asp:Parameter Name="Site" Type="String" />
<asp:Parameter Name="Active" Type="Boolean" />
</InsertParameters>
<UpdateParameters>
<asp:Parameter Name="AccountNumber" Type="String" />
<asp:Parameter Name="Active" Type="Boolean" />
</UpdateParameters>
</asp:SqlDataSource>
CS:
public partial class Admin_CustomerAccountManager : System.Web.UI.Page
{
public string SiteName = WebConfigurationManager.AppSettings["Site"].ToString();
protected void Page_Load(object sender, EventArgs e)
{
Label LBXTitle = (Label)Master.FindControl("lbxTitle");
LBXTitle.Text = "Customer Sapphire Account Number Manager";
if (!this.IsPostBack)
{
SqlDataSource1.SelectParameters.Add("Site", DbType.String, SiteName);
}
}
protected void dd_Status_SelectedIndexChanged(object sender, EventArgs e)
{
RadGrid1.DataBind();
}
protected bool GenerateBindString(object dataItem)
{
bool ret = false;
// if column is null set checkbox.checked = false
if ((DataBinder.Eval(dataItem, "Active")).ToString() == "")
ret = false;
else // set checkbox.checked to boolean value in Status column
ret = (bool)DataBinder.Eval(dataItem, "Active");
return ret;
}
protected void RadGrid1_ItemCommand(object source, Telerik.Web.UI.GridCommandEventArgs e)
{
Page.Validate();
if (Page.IsValid)
{
if (e.CommandName == "PerformInsert")
{
GridEditFormItem gridEditFormItem = (GridEditFormItem)e.Item;
Label lblID = (Label)gridEditFormItem.FindControl("lblID");
TextBox txtAccountNumber = (TextBox)gridEditFormItem.FindControl("txtAccountNumber");
CheckBox cbActive = (CheckBox)gridEditFormItem.FindControl("cbActive");
bool isActive = true;
string SqlStr = "INSERT INTO [LBX_Portal_AccountNumbers] ([AccountNumber], [Site], [Active])";
SqlStr += " VALUES ('" + txtAccountNumber.Text + "'" + ", '" + SiteName + "'" + ", '" + isActive + "')";
SqlDataSource1.InsertCommand = SqlStr;
SqlDataSource1.Insert();
}
if (e.CommandName == "Update")
{
GridEditFormItem gridEditFormItem = (GridEditFormItem)e.Item;
Label lblID = (Label)gridEditFormItem.FindControl("lblID");
TextBox txtAccountNumber = (TextBox)gridEditFormItem.FindControl("txtAccountNumber");
CheckBox cbActive = (CheckBox)gridEditFormItem.FindControl("cbActive");
bool isActive = false;
if (cbActive.Checked)
isActive = true;
else
isActive = false;
string SqlStr = "UPDATE [LBX_Portal_AccountNumbers] SET [AccountNumber] = '" + txtAccountNumber.Text;
SqlStr += "', [Active] = '" + isActive + "' WHERE [ID] = " + lblID.Text;
SqlDataSource1.UpdateCommand = SqlStr;
SqlDataSource1.Update();
}
}
}
protected void cvAccountNumber_ServerValidate(object source, ServerValidateEventArgs args)
{
TextBox txtAccountNumber = RadGrid1.FindControl("txtAccountNumber") as TextBox;
List<GridDataItem> Items = (from item in RadGrid1.Items.Cast<GridDataItem>()
where item["AccountNumberView"].Text == txtAccountNumber.Text
select item).ToList();
args.IsValid = Items.Count() == 0;
}
}
It looks that GridView.FindControl inside validate event never works, how ever you can access string that needs to be validated like this:
This is how you validate target control value:
protected void cvAccountNumber_ServerValidate(object source, ServerValidateEventArgs args)
{
string textToBeValidated = args.Value;
}
And here is how you can access actual controls. GridView.FindControl will end up with nothing when using inside ServerValidate context, so you have to look inside edited/inserted row.
protected void cvAccountNumber_ServerValidate(object source, ServerValidateEventArgs args)
{
//find your editing row...
GridViewRow editedRow = RadGrid1.Rows[RadGrid1.EditIndex];
//now serch row for your control...
TextBox txtAccountNumber = (TextBox)editedRow.FindControl("txtAccountNumber");
TextBox txtId = (TextBox)editedRow.FindControl("txtId");
}