Passing two values through CommandArgument and splitting it
I'm using the commandArgument property of the LinkButton ( Which is wrapped inside a repeater ) to pass two values -as one string- to a second repeater then I try to split them into two values, So I could use them as parameters in my ADO.NET Code (SqlCommand Parameters)....after testing my queries don't r开发者_StackOverflow社区eturn any results but If I passed fixed values for the parameter or change the source of the parameter (just for test from a textbox or querystring or something) I get my results, so I think the problem is in splitting.
I Conduct some arugment values from the ArgumentCommand property of the LinkButton -which is wrapped inside a repeater:
<ItemTemplate>
<asp:LinkButton id="sort_lnkbtn" Text='<%# Eval("value")%>'
CommandArgument='<%#string.Format("{0}|{1}",Eval("arrange_by_id"),Eval("value"))%>' runat="server">
</asp:LinkButton>
</ItemTemplate>
Then I receive these values and cut them into two pieces of information:
string sortByAndArrangeBy = (e.CommandArgument).ToString();
char[] separator = { '|' };
string[] sortByAndArrangeByArray = sortByAndArrangeBy.Split(separator);
Now the ado.net code uses this values as a
using (SqlConnection cn1 = new SqlConnection(ConfigurationManager.ConnectionStrings["testConnectionString"].ConnectionString))
{
using (SqlCommand cm1 = new SqlCommand("SELECT [name] FROM brands WHERE (name like @SearchString + '%' )", cn1))
{
cm1.Parameters.Add("@SearchString", System.Data.SqlDbType.Char);
cm1.Parameters["@SearchString"].Value = sortByAndArrangeByArray[1];
cn1.Open();
using (SqlDataReader dr1 = cm1.ExecuteReader())
{
List_rpt.DataSource = dr1;
List_rpt.DataBind();
}
}
}
Here is a simple solution:
Wrap your item template for the repeater in a control. The control will have the same markup as your item template without the bindings:
Control Markup:
<div>
<asp:LinkButton ID="LnkBtnSort" runat="server" Text="Sort" OnClick="LnkBtnSort_Clicked"/>
</div>
Control Code:
public class SomeControl
{
public event EventHandler Click;
public string ArrangeById
{
set { ViewState["byid"] = value; }
get { return ViewState["byid"].ToString(); }
}
public string Value
{
set { ViewState["val"] = value; }
get { return ViewState["val"].ToString(); }
}
protected void LnkBtnSort_Clicked(object sender, EventArgs e)
{
if( Click != null )
{
this.Click(this, EventArgs.Empty);
}
}
}
So now in the repeater all you have to do is bind an instance of that control to the Container.DataItem:
<ItemTemplate>
<ctrl:SomeControl
ID="someControl"
runat="server"
OnClick="SomeControl_Clicked"
ArrangeById='<%# Eval("arrange_by_id") %>'
Value='<%# Eval("value") %>' />
</ItemTemplate>
The page/control that has the repeater will have one simple method:
protected void SomeControl_Clicked(object sender, EventArgs e)
{
//Here cast the sender to the type of control you made:
SomeControl ctrl = (SomeControl)sender;
string byId = ctrl.ArrangeById;
string val = ctrl.Value;
}
Note: this code may not be 100% correct but it illustrates the point. The flow is simple - the control binds its public properties to whatever you need to bind. When the link is clicked (inside your control) the control doesn't propagate this event to the page. Instead it fires its own event (Click) thus sending a signal to the page that an event occured. however by doing so, it changes the source of the event to itself instead of the actual link button. The page handles the event and everyone is happy.
This way you don't have to care what the CommandArgument is... If this comes up empty, it means that either your data source is empty... or something else happened in the code.
精彩评论