Bind SC Images in Sitecore - c#

I'm having a repeater control and want to bind Images to the sc control for onitemdatabound event.
My markup is:
<sc:Link runat="server" ID="sclnk" Field="#" rel="iframe-960-540">
<sc:image id="scimage" runat="Server" field="#">
</sc:image>
</sc:Link>
And my code is:
Sitecore.Web.UI.WebControls.Link scBannerLink = e.Item.FindControl("sclnk") as Sitecore.Web.UI.WebControls.Link;
if (scBannerLink != null)
{
scBannerLink.DataBind(promoItem.ID.ToString(), promoItem.PromoLink.Field.InnerField.Name);
}
Sitecore.Web.UI.WebControls.Image scPromoImage = e.Item.FindControl("scimage") as Sitecore.Web.UI.WebControls.Image;
if (scPromoImage != null)
{
scPromoImage.DataBind(promoItem.ID.ToString(), promoItem.PromoImage.Field.InnerField.Name);
}
I'm not getting any error but not diaplaying images

I've never used the Databind method of the control to set the properties.
The easier solution is to specify the Fieldname and set the Item in your repeater:
<asp:Repeater runat="server" ID="rptImages">
<ItemTemplate>
<sc:Link runat="server" ID="scLnk" Field="MyLinkFieldName" Item="<%# Container.DataItem %>" Parameters="rel=iframe-960-540">
<sc:image id="scImage" runat="Server" Field="MyImageFieldName" Item="<%# Container.DataItem %>" />
</sc:Link>
</ItemTemplate>
</asp:Repeater>
And you can pass in the additional attributes in the Parameters field on the control as a URL encoded parameters string, e.g. Parameters="rel=iframe-960-540&param2=value2&param3=value3"
And your code behind binding the control should be:
protected void Page_Load(object sender, EventArgs e)
{
rptImages.DataSource = Sitecore.Context.Item.GetChildren(); // this needs to be changed to whatever your query is...
rptImages.DataBind();
}

Related

System.Web.HttpException: 'DataBinding: 'System.Web.UI.WebControls.SqlDataSource' does not contain a property with the name 'Name'.'

I am working on a project with RadTreeView.
I am trying to bind the Nodes with names coming from db.
Data binding is done when the remark panel is opened(when 'Remark' is clicked' so not in Page_Load because Page Load is just for opening the main page. If I am wrong please correct me.
However, I am getting the error:
System.Web.HttpException: 'DataBinding: 'System.Web.UI.WebControls.SqlDataSource' does not contain a property with the name 'Name'.'
Please find my server and clients code as below.
.ascx
<telerik:RadScriptBlock ID="RadScriptBlock1" runat="server">
<script>
function OpenEditWindow() {
var appWindow = $find("<%=rdwRemark.ClientID%>");
appWindow.show();
}
function CloseEditWindow() {
var appWindow = $find("<%=rdwRemark.ClientID%>");
appWindow.close();
}
</script>
</telerik:RadScriptBlock>
<telerik:RadWindow ID="rdwRemark" runat="server" Title="Remark"
Width="375" Height="400"
Behaviors="Close"
Modal="true"
CenterIfModal="true"
Skin="Telerik">
<ContentTemplate>
<telerik:RadAjaxPanel ID="RadAjaxPanel3" runat="server">
<asp:HiddenField ID="hdnOrderId" runat="server" />
<telerik:RadTreeView RenderMode="Lightweight" runat="server" ID="RadTreeView1"
EnableDragAndDrop="false"
OnClientNodeDropping="onDropping" EnableDragAndDropBetweenNodes="false">
<Nodes>
<telerik:RadTreeNode runat="server" Text="Alt Yuklenici" AllowDrag="false">
<NodeTemplate>
<%#DataBinder.Eval(SqlDataSource1 , "Name") %>
</NodeTemplate>
</telerik:RadTreeNode>
</Nodes>
</telerik:RadTreeView>
<asp:SqlDataSource runat="server" ID="SqlDataSource1" ConnectionString="<%$ ConnectionStrings:TTMS_DB %>"
SelectCommand="Select [Name] from [TTMS].[P21].[P_Master_Subcontractors] "></asp:SqlDataSource>
</telerik:RadAjaxPanel>
</ContentTemplate>
</telerik:RadWindow>
.ascx.cs
protected void grdOrder_ItemCommand(object sender, GridCommandEventArgs e)
{
if (e.CommandName == "Remark")
{
RadTreeView1.DataBind(); //data bind is done when Remark is clicked.
var orderval = (e.Item as GridDataItem).GetDataKeyValue("ORDER_ID").ToString();
var orderData = pmsSrv.GetOrderByOrderId(orderval.ToInt());
//var textbox = RadAjaxPanel3.FindControl("textbox") as TextBox;
//textbox.Text = orderData.Remark;
(RadAjaxPanel3.FindControl("hdnOrderId") as HiddenField).Value = orderval;
pmsSrv.ResponseScript("OpenEditWindow()");
return;
}
}
Even 'Name' exists in the db the code cannot find it.
Any help is appreciated.
Thanks,
Kind Regards.
As far as I know DataBinder.Eval() used to evaluate data-binding expression from object container, such like Container.DataItem. Since SqlDataSource doesn't have Name property, you can't use that for data binding with RadTreeNode.
Instead, you need to use Container.DataItem for data binding purpose:
<%# DataBinder.Eval(Container.DataItem, "Name") %>
Also don't forget to bind RadTreeView to the data source by setting DataSourceID, DataTextField and DataValueField like example below:
<telerik:RadTreeView RenderMode="Lightweight" runat="server" ID="RadTreeView1"
EnableDragAndDrop="false"
DataSourceID="SqlDataSource1"
DataTextField="Name"
DataValueField="Name"
OnClientNodeDropping="onDropping" EnableDragAndDropBetweenNodes="false">
</telerik:RadTreeView>
References for further reading:
RadTreeView - Binding to ASP.NET DataSource Components (Telerik Docs)
RadTreeView - Data Binding Overview (Telerik Docs)

How to get an item from asp:Repeater in Event handler?

I have a Repeater that is binded with some DataTable. (Here I skiped header template).
<asp:Repeater ID="rpt_users" runat="server" OnItemCommand="rpt_users_ItemCommand" OnItemDataBound="rpt_users_ItemDataBound">
<ItemTemplate>
<tr class="c0">
<td><asp:CheckBox ID="CheckSelect" runat="server" /></td>
<td>
<asp:HyperLink ID="hpl_edit" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "name") %>'
NavigateUrl='<%# DataBinder.Eval(Container.DataItem, "edit") %>'></asp:HyperLink></strong>
<asp:LinkButton ID="btn_del" runat="server" CommandName="Remove" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "key") %>'><img src="assets/img/delete.png" alt="<%#nodeDelete %>" title="<%#nodeDelete %>" class="ico-delpage icon-right" /></asp:LinkButton>
</td>
<td>
<p><%# DataBinder.Eval(Container.DataItem, "country") %></p>
</td>
<td>
<asp:TextBox runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "daysleft") %>' OnTextChanged="Unnamed_TextChanged" AutoPostBack="true"/>
</td>
</tr>
</ItemTemplate>
<asp:Repeater>
I associated OnTextChanged event with a handler:
protected void Unnamed_TextChanged(object sender, EventArgs e)
{
var txt = (sender as TextBox).Text;
int newDays = 0;
try
{
newDays = int.Parse(txt);
}
catch { return; }
}
So, how to get the whole object that is associated with current row in Repeater? I need to get access to this object in my OnTextChanged event handler, because I need to get some data from this object that represents current row.
You cannot access the bound object of the repeater item in the OnTextChanged event. One way of doing this is as follows.
After retrieving the datatable, save the datatable in viewstate
ViewState["Data"] = data;
Bind the key value of the individual item to a hidden field by adding a hidden field to the repeater item
< asp:HiddenField runat="server" ID="hiddenFieldKey" Value='<%# DataBinder.Eval (Container.DataItem, "key") %>' />
You can get the, repeater item and then the hidden field, to get the key of the row. Then the other values can be retrieved by finding the rows in the table which is stored in the viewstate.
protected void Unnamed_TextChanged(object sender, EventArgs e)
{
var txt = (sender as TextBox).Text;
var repeaterItem = (sender as TextBox).NamingContainer as RepeaterItem;
var hiddenFieldKey =repeaterItem.FindControl("hiddenFieldKey") as HiddenField;
// Get data from viewstate
DataTable data = ViewState["Data"] as DataTable;
var dataRow= data.Rows.Find(hiddenFieldKey.Value);
//You can use this row to get the values of the other columns
int newDays = 0;
try
{
newDays = int.Parse(txt);
}
catch { return; }
}
Another way of doing is that, if you dont have many values to get, then bind all the required values in multiple hidden fields in the repeater item and then get those hidden field values in the OnTextChanged event
You can use the sender parameter, like you do for Text, var tb = (TextBox)sender;, then access that control's Parent property. You might have to go a couple levels up to find exactly what you're looking for, but that's the gist. Then you can use FindControl or whatever you need past that.

How to access control inside parent control? (asp.net c#)

I have page with listview in it. There is label and dropdownlist in listview. I would like to access the text of label from ddlTags_Init() method.
Code:
<asp:ListView ID="ListView1" runat="server" DataSourceID="SqlDataSource1"
DataKeyNames="id_Image" onitemdatabound="ListView1_ItemDataBound">
<ItemTemplate>
<asp:Label ID="TagsLabel" runat="server" Text='<%# Eval("Tags") %>' />
<asp:DropDownList ID="ddlTags" runat="server" OnInit="ddlTags_Init" >
</asp:DropDownList>
</ItemTemplate>
</asp:ListView>
Code behind:
protected void ddlTags_Init(object sender, EventArgs e)
{
DropDownList ddlTags = (DropDownList)sender;
Label lblTag = (Label)ddlTags.Parent.FindControl("TagsLabel");
string text=lblTag.Text;
}
At the moment i am stuck with
Label lblTag = (Label)ddlTags.Parent.FindControl("TagsLabel");
Anyone knows what am i missing?
Thanks, Jim
Assuming that there are more than 1 elements in the listview datasource, why don't you put your code in the ItemDataBound handler? I think that it should work.
Init is too early to get the bind value of Label. In other words, label value hasn't been bind yet.
Instead you might want to consider using ItemDataBound method.
<asp:ListView ID="ListView1" runat="server"
OnItemDataBound="ListView1_ItemDataBound" ...>
....
</asp:ListView>
protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
var ddlTags = e.Item.FindControl("ddlTags") as DropDownList;
var tagsLabel = e.Item.FindControl("TagsLabel") as Label;
}
}

Rebinding on Postback Based on Selected DropDown Value

Greetings!
I have a DropDownList within a FormView which are bound to XmlDataSources:
<asp:FormView ID="MyFormView" runat="server" DataSourceID="MyXmlDataSource">
<ItemTemplate>
<h1><%# XPath("SomeNode")%></h1>
<asp:Label ID="MyLabel" runat="server" AssociatedControlID="MyDdl" Text='<%# XPath("SomeOtherNode")%>' />
<asp:DropDownList ID="MyDdl"
runat="server"
DataSourceID="MyDdlDataSource"
DataTextField="name"
DataValueField="value"
AutoPostBack="true"
OnSelectedIndexChanged="MyDdl_SelectedIndexChanged">
</asp:DropDownList>
</ItemTemplate>
</asp:FormView>
<asp:XmlDataSource ID="MyXmlDataSource" runat="server" XPath="Root/MainSection" />
<asp:XmlDataSource ID="MyDdlDataSource" runat="server" XPath="Root/MainSection/Areas/*" />
In the page's codebehind, I have the following OnLoad() method as well as the method for when the select index of the dropdownlist changes:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (!IsPostBack)
{
string xml = GetMyXml(0); // default value
MyXmlDataSource.Data = xml;
MyDdlDataSource.Data = xml;
}
}
protected void MyDdl_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList l_MyDdl = FindControl("MyDdl") as DropDownList;
int myVal;
if (l_MyDdl != null)
if (!Int32.TryParse(l_MyDdl.SelectedItem.Value, out myVal))
myVal = 0;
string xml = GetMyXml(myVal);
MyXmlDataSource.Data = xml;
MyDdlDataSource.Data = xml;
}
When a different value is selected from the dropdown list and SelectedIndexChanged is invoked, I am unable to get the value of the dropdown list (FindControl always returns null) in order to use it to re-bind the datasources. How can I get this value?
Because your dropdownlist is contained within another control it may be that you need a recursive findcontrol.
http://weblogs.asp.net/palermo4/archive/2007/04/13/recursive-findcontrol-t.aspx

How to pass in runtime a index of row for ListView?

I have an question, On my page i have a ListView control, I also have a button that has CommandArgument. I know i can read and find a control in the ListView as :
ListView.Items[i].FindControl("controlname");
and my button in ListView is like that
asp:Button ID="WisdomButton" runat="server" CommandName="UpdateWisdom" CommandArgument='<%# need my index for Item[i] to post here %>'
OnCommand="UpdateWisdom" Text="Update" />
I want to add index value in runtime to the CommantParameter, so when i go to the Function onCommand i will know exactly from what row[i] i Need to get my controls from ListView.
So my question is, how do i dinamicly add index of ListView.Rows[i] into CommmandArgument for the Button in runtime ?
Thanks in advance.
Check out the API
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listviewcommandeventargs.aspx
The ListViewCommandEventArgs item has an index, IE it is already available in the argument
ListViewDataItem dataItem = (ListViewDataItem)e.Item;
int i = dataItem.DisplayIndex;
But from here you will have access to those controls
e.Item.FindConrol("controlName");
If you are calling the method a different way you could aways assign the index through an ItemDataBound Event
void MyListView_ItemDataBound(object sender, ListViewItemEventArgs e)
{
((Button)e.Item.FindControl("WisdomButton")).CommandArgument = ((ListViewDataItem)e.Item).DisplayIndex;
}
OR try something like this for giggles
<asp:Button runat="server" CommandArgument='<%# DisplayIndex %>'/>
// OR
<asp:Button runat="server" CommandArgument='<%# NextIndex() %>'/>
It might help to know a little bit more about what your are trying to do. If your end goal is to get any of the properties from your bound object you can just cast the dataItem from the ListViewCommandEventArgs of the ItemCommand event. You don't need to retain the index or call FindControl at all.
Here is an example of how to get the bound Customer object.
ListView
<asp:ListView runat="server" id="Customers" ItemCommand="Customers_ItemCommand">
<LayoutTemplate>
<ul>
<asp:placeholder runat="server" id="itemPlaceholder" />
</ul>
</LayoutTemplate>
<ItemTemplate>
<li>
<asp:Button runat="server" id="Select" CommandName="Select" />
<%# Eval("Name")%>
</li>
</ItemTemplate>
</asp:ListView>
CodeBehind
public void Page_Load()
{
if (!Page.IsPostBack)
{
this.Customers.DataSource = GetCustomers();
this.Customers.DataBind();
}
}
public void Customers_ItemCommand(object sender, ListViewCommandEventArgs e)
{
if (e.CommandName == "Select")
{
if (e.Item.ItemType != ListViewItemType.DataItem)
return;
var customer = ((ListViewDataItem)e.Item).DataItem as Customer;
if (customer != null)
{
// Now work directly with the customer object.
Response.Redirect("viewCustomer.aspx?id=" + customer.Id);
}
}
}
Edit: In addtion when you cast the item to a ListViewDataItem, then you also expose a ((ListViewDataItem)e.Item).DataItemIndex property that might help you.

Categories