Usercontrol in EditItemTemplate of templated control. How to achieve two-way databinding? - asp.net

I was hoping to replace the EditItemTemplate of an ASP.NET ListView with a user control but I can't work out how to bind it to the data item in the ListView to achieve two-way data binding. The data item isn't a simple property. It's an object.
This seems only to give one-way Eval type databinding:
<EditItemTemplate>
<uc:MyUserControl id="thecontrol" runat="server" TheObject='<%# Container.DataItem %>'/>
</EditItemTemplate>
This gives an error:
<EditItemTemplate>
<uc:MyUserControl id="thecontrol" runat="server" TheObject='<%# Bind("Container.DataItem") %>'/>
</EditItemTemplate>
As does this:
<EditItemTemplate>
<uc:MyUserControl id="thecontrol" runat="server" TheObject='<%# Bind("this") %>'/>
</EditItemTemplate>
Is there some binding expression syntax to give two-way databinding to the current item in an EditItemTemplate?
Edit. This is the user control:
public partial class EditItemUserControl : System.Web.UI.UserControl
{
public TestObject TheObject
{
get
{
return new TestObject() { ID = Int32.Parse(hfID.Value), Name = txtName.Text };
}
set
{
hfID.Value = value.ID.ToString();
txtName.Text = value.Name;
}
}
protected void Page_Load(object sender, EventArgs e)
{
}
}

Just for reference. I was doing it wrong. A user control lives in the context of the page where it's rendered so there's no need to set a DataSource on it. In the .ascx file you can just use:
Text = '<%# Bind("MyProperty") %>'
or
Text = '<%# Eval("MyProperty") %>'
where MyProperty is some property of the parent control's DataSource.

Related

Data binding along with the value in ASP.NET

How do you achive something like below in asp.net?
<asp:Label runat="server" Text="The '<%# CustomValue %>' you assigned."/>
This usually depends on where your Label resides. If it is a stond alone control, not nested inside a repeater, you just set your code in code behind:
Label1.Text = $"The {CustomValue} you assigned.";
If the label is nested inside an ItemTemplate in some sort of Repeater control, you can strongly type it to an objects property:
<asp:Repeater runat="server" ID="MyRepeater" ItemType="WebFormsSandbox.Person">
<ItemTemplate>
<li>
<%#: Item.FirstName %> <%#: Item.LastName %>
</li>
</ItemTemplate>
</asp:Repeater>
and the corresponding code behind:
protected void Page_Load(object sender, EventArgs e)
{
MyRepeater.DataSource = Persons();
MyRepeater.DataBind();
}
IEnumerable<Person> Persons()
{
for (int i = 0; i < 10; i++)
{
yield return new Person { Id= i, FirstName = $"Foo{i}", LastName = $"Bar{i}" };
}
}
This would create a list of links, where you then could do anything with it. Whether this would pop up a custom window or does a postback .. up to you.
If you really want to do it that way, write the string inside the server tags.
<asp:Label runat="server" Text='<%# "The " + CustomValue + " you assigned." %>'/>
However if the Label is not inside a GridView, Repeater etc you have to call DataBind manually.
protected void Page_Load(object sender, EventArgs e)
{
DataBind();
}
You would typically do this in the code behind on page load, unless you were using a datagrid or repeater control. Assign an ID to your control and reference it like so.
<asp:Label runat="server" ID="Label1" />
protected void Page_Load(object sender,EventArgs e)
{
Label1.Text = "Your Value";
}

User Control inside Repeater - Values lost on PostBack - RadRating

I have a UserControl Inside a repeater, coded in the following way:
ParentPage.aspx:
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<uc1:MovieDetailPanel runat="server" myMovieID='<%# Eval("movieID") %>' myMovieName='<%# Eval("movieName") %>'
myMovieDescription='<%#Eval("movieDescription") %>' myMovieImagePath='<%# Eval("posterImage") %>'
myMovieYear ='<%# Eval("movieYear") %>' myMovieGenre ='<%# Eval("movieGenre") %>' myMovieAverageRating ='<%# Eval("movieRating") %>'
myMovieCountry ='<%# Eval("movieCountry") %>' myMovieLanguage ='<%# Eval("movieLanguage") %>'
id="MovieDetailPanel1" />
</ContentTemplate>
</ItemTemplate>
</asp:Repeater>
ParentPage.cs:
private void LoadMyControls()
{
Repeater1.DataSource = new Common().getMoviesList(selectedGenre, selectedYear, selectedPopularity, selectedLanguage, selectedCountry);
Repeater1.DataBind();
}
UserControl.cs:
public int myMovieID { get; set; }
public string myMovieName { get; set; }
public double myMovieAverageRating { get; set; }
//some more properties
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
MovieRatingControl.Value = myMovieAverageRating ;
}
}
I have a Telerik RadRating (ID# MovieRatingControl) in my UserControl. On page load of the UserControl I am setting the value of the rating control, as passed by repeater from Database (wrapped it inside if(!Page.IsPostBack) as shown above. So each movie gets its own rating as present in the database.
However, on postback (when I click the rate button), the RadRating Control loses its value and becomes 0. This happens on all the UserControls inside the repeater and not just the UserControl in which I clicked the Rate button. Can someone please let me know how I am supposed to retain this rating value ? I need to get that and update my DB Tables.
P.S: If im not using if (!Page.IsPostBack), I retain values from DB but not the rating set by the user. The issue is, the rating set by user is not maintained.

Ajax autocomplete extender and get ID of selected item?

I am using the autocomplete extender to suggest names when a user types. How to get the select value after the user selects an item? I guess I can use onclientitemselected but I am not familiar on how to write this? I need to populate a textbox based on the selection in the autocompleteextender textbox. Thank you
<asp:TextBox ID="TextBox1" runat="server" Height="27px" Width="570px"></asp:TextBox>
<asp:AutoCompleteExtender ID="AutoCompleteExtender" runat="server"
DelimiterCharacters="" Enabled="True" ServicePath="AutoComplete.asmx"
ServiceMethod="GetCompletionList" TargetControlID="TextBox1"
MinimumPrefixLength="2" UseContextKey="true" ContextKey="StateDropDown"
CompletionListElementID="autocompleteDropDownPanel">
</asp:AutoCompleteExtender>
For this you need to return the list from web service method with ID and Text
Here "lst" is the actual list with data from your data source.
List<string> items = new List<string>(count);
for (int i = 0; i < lst.Count; i++)
{
string str =AjaxControlToolkit.AutoCompleteExtender.CreateAutoCompleteItem(lst[i].Text,Convert.ToString(lst[i].IDValue));
items.Add(str);
}
return items.ToArray();
Then simple javascript
function GetID(source, eventArgs )
{
var HdnKey = eventArgs.get_value();
document.getElementById('<%=hdnID.ClientID %>').value = HdnKey;
}
and dont forget to set the attribute in auto complete extender
OnClientItemSelected="GetID"
The AutoCompleteExtender merely extends the ASP.NET TextBox control, so if you want to know when the text changed, then just raise the TextChanged event on the TextBox control, like this:
Markup:
<asp:TextBox ID="TextBox1" runat="server" Height="27px" Width="570px" OnTextChanged="TextBox1_TextChanged" AutoPostBack="true"></asp:TextBox>
Code-Behind:
protected void TextBox1_TextChanged(object sender, EventArgs e)
{
// Do something here with textbox value
}

Required field validater in repeater

I have a repeater control and textbox in that repeater. I want a required field validator in the textbox ho can i do this
<asp:Repeater id="myRep" OnItemDataBound="rep_ItemDataBound" runat="server">
<ItemTemplate>
<asp:TextBox id="tx" runat="server" />
<asp:RequiredFieldValidator id="myVal" ControlToValidate="tx" ErrorMessage="Required" runat="server" />
</ItemTemplate>
</asp:Repeater>
UPDATE
Add this to code-behind (also modify the markup a bit to subscribe to an event, see above):
protected void rep_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
RequiredFieldValidator val = (RequiredFieldValidator)e.Item.FindControl("myVal");
TextBox tb = (TextBox)e.Item.FindControl("tx");
val.ControlToValidate = tb.ID;
}
If you want all textboxes in a repeater to be validated by a single button click then thats simple like this
<asp:Repeater ID="rpt" runat="server">
<ItemTemplate>
<asp:TextBox ID="txt" runat="server">
</asp:TextBox>
<asp:RequiredFieldValidator ID="rqf" ControlToValidate="txt"
ErrorMessage="*" ValidationGroup = "TestValidationGroup" runat = "server">
</asp:RequiredFieldValidator>
</ItemTemplate>
</asp:Repeater>
<asp:Button ID = "btnSubmit" runat = "server" ValidationGroup = "TestValidationGroup" />
No need to check for any event for databound or anything.
You can set ControlToValidate value on repeater itemdatabound.
Try this one
<asp:Repeater ID="rptSample" runat="server">
<ItemTemplate>
Name:<br />
<asp:TextBox ID="txtName" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="rfvName" ControlToValidate="txtName" runat="server" Display="Static" ErrorMessage="Name field cannot be left blank"></asp:RequiredFieldValidator>
</ItemTemplate>
</asp:Repeater>
<br />
<asp:Button ID="btnSubmit" Text="Submit" runat="server" />
protected void myRep_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
((RequiredFieldValidator)e.Item.FindControl("myVal")).ValidationGroup = ((TextBox)e.Item.FindControl("tx")).UniqueID;
}
}
protected void Repeater_OnItemDataBound(object sender, RepeaterItemEventArgs e) {
tblData tbldata = e.Item.DataItem as tblData;
RequiredFieldValidator val = (RequiredFieldValidator)e.Item.FindControl("rfv");
if (tbldata.FieldName.ToUpper().Contains("NOT NULL")) {
TextBox tb = (TextBox)e.Item.FindControl("txtDATFieldName");
val.ControlToValidate = tb.ID;
}
else {
val.Enabled = false; // disable when you dont need a validator
}
}
Maybe you want have a validation per row... Set the validation group to a group per row like this
ValidationGroup='<%# "gropname" + Eval("Id") %>'
do this in the validator, textbox and the button
HTH
G.
I kept getting a duplicate key exception in RegisterExpandoAttribute trying to do this.
I was using a UserControl inside a repeater, when "OnDataBinding" instead of "ItemDataBinding"
This worked for me:
/// <summary>
/// Raises the <see cref="E:System.Web.UI.Control.DataBinding" /> event.
/// </summary>
/// <param name="e">An <see cref="T:System.EventArgs" /> object that contains the event data.</param>
protected override void OnDataBinding(EventArgs e)
{
base.OnDataBinding(e);
foreach (Control ct in this.Controls)
{
BaseValidator bv = ct as BaseValidator;
if (null == bv)
{
continue;
}
bv.ControlToValidate = this.FindControl(bv.ControlToValidate).ID;
bv.ValidationGroup = this.ValidationGroup;
}
}
And yes, I don't think it makes any sense either

Use data in repeater when Checkbox is check in ASP.net

I have a repeater for showing my data . this repeater showing 2 field that one of feild is checkBox Control and other is a lable.
NOW , how can I understand text of lable when the checkBox is Checked?
I want to see text of lable in evry row that the CheckBoxes is checksd.
how do I do?
I use LINQtoSQL for get and set data from database
On postback, you need to loop through every row of your repeater, and grab out the checkbox control. Then you can access it's .Checked and .Text properties. If it's .Checked, then add it to a list or array. I can elaborate if needed..
Page...
<asp:CheckBox ID="chkBoxID" runat="server" OnCommand="doSomething_Checked" CommandArgument="<%# Some Binding Information%>"
CommandName="NameForArgument">
</asp:CheckBox>
Code Behind...
protected void doSomething_Checked(object sender, CommandEventArgs e) {
CheckBox ctrl = (CheckBox)sender;
RepeaterItem rpItem = ctrl.NamingContainer as RepeaterItem;
if (rpItem != null) {
CheckBox chkBox = (LinkButton)rpItem.FindControl("chkBoxID");
chkBox.DoSomethingHere...
}
}
<asp:Repeater ID="rptX" runat="server">
<ItemTemplate>
<asp:Label ID="lblX" runat="server" Visible='<%# Eval("IsChecked") %>' />
<asp:CheckBox ID="chkX" runat="server" Checked='<%# Eval("IsChecked") %>' />
</ItemTemplate>
</asp:Repeater>
And code behind when you assign your data
rptX.DataSource = SomeIEnumerableFromLinq; // which has a bool field called IsChecked
rptX.DataBind();

Resources