Databinding to a View Model not working - asp.net

I have an AJAX Accordion Control sitting on my Web Form. I have a Asp.Net Label sitting inside an Accordion Pane. I want to databind the text property of the label to a View Model I have running.
The Label Text Property never seems to databind with the View Model? It will work perfectly if I pull the label outside of the Accordion Pane, but not inside?
This works:
<asp:Label runat="server" Text='<%# Model.Program.NameVisible.ToString() %>' />
This does not:
<asp:AccordionPane ID="AccordionPane2" runat="server">
<Header>
Advanced Search
</Header>
<Content>
<asp:Panel ID="pnlAdvancedSearch" runat="server">
<table cellpadding="2" cellspacing="0" width="100%" runat="server">
<tr>
<td align="right">
<asp:Label runat="server" Text='<%# Model.Program.NameVisible.ToString() %>' />
</td>
</tr>
</table>
</asp:Panel>
</Content>
</asp:AccordionPane>
Any ideas or workarounds?
Thanks.
Update: This apparently does not work when nested inside any AJAX Controls. I have had the same issue with the binding not taking place inside a ModalPopUpExtender as well.

The DataBind of the Accordion control does not invoke DataBind for each of the explicitly defined, custom AccordionPane controls. It instead will build the panes, as per the answer provided by Jupaol, using templates.
In your example, you will need to explicitly call DataBind on the control you want bound, or on a parent which will invoke databinding on all children. So, in your example, calling pnlAdvancedSearch.DataBind() would suffice to bind your label, and any other controls within the search panel.
I feel it worthwhile to add, however, that it also seems like it would be simpler to replace your <asp:Label> control entirely with a simple:
<%: Model.Program.NameVisible.ToString() %>

I just found a way
First of all the Accordion control does support data binding:
The Accordion can also be databound. Simply specify a data source through the DataSource or DataSourceID properties and then set your data items in the HeaderTemplate and ContentTemplate properties.
Source
Example:
Output
ASPX
<ajax:Accordion runat="server" ID="ajax22" RequireOpenedPane="true"
HeaderCssClass="accordionHeader"
HeaderSelectedCssClass="accordionHeaderSelected"
ContentCssClass="accordionContent"
>
<ContentTemplate>
Even cooler content
<br />
<asp:Label Text='<%# DataBinder.Eval(Container.DataItem, "Something") %>' ID="lbl" runat="server" />
</ContentTemplate>
<HeaderTemplate>
Cool header
<br />
<asp:Label Text='<%# DataBinder.Eval(Container.DataItem, "Something") %>' ID="lbl" runat="server" />
</HeaderTemplate>
</ajax:Accordion>
ASPX code behind
You need to specify the Accordion.DataSource property, this property only supports IEnumerable or IListSource, therefore you would need to bind your accordion as follows:
this.ajax22.DataSource = new[] { this.Model };
this.DataBind();
Model
public class MyModel
{
public MyModel()
{
this.Something = "plop!";
}
public string Something { get; set; }
}
When you bind your Accordion, a number of AccordionPanes are created to represent each bound item.
If you specify additional custom AccordionPanes, when you apply binding as specified above, these AccordionPanes will be ignored and won't be rendered.

Related

How to change the properties of controls in a UserControl at runtime in WebForms

I have a simple UserControl defined as:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="AdminBanner.ascx.cs" Inherits="OrderManager.Controls.AdminBanner" %>
<asp:Panel runat="server" ID="AlertPanel" BorderWidth="1px">
<asp:Label runat="server" ID="LabelTitle" Text="Test!!!!!!!" ></asp:Label>
</asp:Panel>
I include the UserControl on an aspx page like so:
<table style="width: 100%;">
<tr>
<td>
<asp:Panel ID="PanelPreviewBanner" Visible="False" runat="server">
<OrderManager:AdminBanner Id="AdminBanner" Visible="True" runat="server" />
</asp:Panel>
</td>
</tr>
</table>
When I click a button on the web form, I want to not only display the Panel, but also change the default value of the LabelTitle in the UserControl. I can show the Panel like this:
// Display the Preview Panel.
this.PanelPreviewBanner.Visible = true;
If I try to change the LabelTitle of the USerControl, wither using the ID of the UC or by way of a property in the UserControl, I always get an error stating that the control is null.
My ultimate goal is to be able to set the css class and style on objects defined in my UserControl.
I have tried numerous examples I found here and through Google and nothing works.
I am assuming you've already done this -
A public property in your AdminBanner.ascx.cs that exposes label's text property to be set by the parent page
public string LabelTitleValue
{
get { return LabelTitle.Text; }
set { LabelTitle.Text = value; }
}
Below is how you should be able to get/set the usercontrol's label text.
AdminBanner.LabelTitleValue = "Test changed";
var text = AdminBanner.LabelTitleValue;
In case you've already done this, you may first try removing your user-control outside the panel (something like below) and at least confirm that user-control is being displayed.
<td>
<asp:Panel ID="PanelPreviewBanner" Visible="False" runat="server"></asp:Panel>
<OrderManager:AdminBanner Id="AdminBanner" Visible="True" runat="server" />
</td>
If it's displaying properly, you may do below in addition to setting panel's visibility
// Display the Preview Panel.
this.PanelPreviewBanner.Visible = true;
this.AdminBanner.Visible = true;

how to bind memory stream to asp.net image controls with out using image url

We have a new requirement to show the signature image in result grid for each record. Currently we store the signature image as base64 format in our database .we are able to convert base 64 to memory stream.
We want to understand does any of your image control support to bind image from memory stream instead of Url .
You could keep images as base64 string form, and use data url.
The following is a example.
<asp:Image runat="server" ID="myImage" />
The code behind is
this.myImage.ImageUrl = "data:image/png;base64,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";
The premise is that you need to know all the MIME type of images.
Reference: data URIs
Sure, you can do it this way.
A gridview, listview, repeater control - they can all do this.
So markup for a grid view:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="Animal" HeaderText="Animal" ItemStyle-Width="200px"/>
<asp:TemplateField HeaderText="Picture">
<ItemTemplate>
<asp:Image ID="Image1" runat="server"
Height="128px" Width="128px"
src='<%# "Data:Image/png;base64," + Eval("Image") %>'
/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And the code to load up the gridview would be:
protected void Page_Load(object sender, System.EventArgs e)
{
if (System.Web.UI.Page.IsPostBack == false)
LoadGrid();
}
public void LoadGrid()
{
using (SqlCommand cmdSQL = new SqlCommand("SELECT Animal, Image from tblAnimals",
new SqlConnection(My.Settings.TEST4)))
{
cmdSQL.Connection.Open();
GridView1.DataSource = cmdSQL.ExecuteReader;
GridView1.DataBind();
}
}
Results:
Now I used a direct eval expression - but you could also use the ItemDataBound event of the gridview (or list view).
Also, I did hard code the "mine" type in above (assumed .png). You often might want to consider to save the file/mine type as a extra column in the database. But, if the picture types are to be all the same types - then a hard code right in the expression as per above will work fine.
If you have a lot of columns for this grid, then I tend to switch over to listview, since each column does NOT need a template, and I find for quick and dirty - grid view is ok, but listview is better for tweaking and lots of customizing. The trick is to get Visual Studio to generate the template + markup, and then blow out all templates except for item template. When you do this, then the crazy truckload of markup is reduced down to "easy" levels. And you can then with greater ease drop in controls - and you don't have template them.
So, the same listview for above would be this:
<asp:ListView ID="ListView1" runat="server">
<ItemTemplate>
<tr style="">
<td><asp:Label ID="AnimalLabel" runat="server" Text='<%# Eval("Animal") %>' /></td>
<td>
<asp:Image ID="ImageT1" runat="server"
Height="128px" Width="128px"
src='<%# "Data:Image/png;base64," + Eval("Image") %>'
/>
</td>
</tr>
</ItemTemplate>
<LayoutTemplate>
<table id="itemPlaceholderContainer" runat="server" border="0" style="">
<tr runat="server" style="">
<th runat="server" width="200">Animal</th>
<th runat="server">Image</th>
</tr>
<tr id="itemPlaceholder" runat="server">
</tr>
</table>
</LayoutTemplate>
</asp:ListView>
So there is somewhat "more" markup, but you can with much greater ease drop in asp.net controls - and you don't have add a templatefield - (about 4 extra lines of markup for every column - so in the long run, I like the listview.
it looks quite much the same, like this:
And the behind code would be 100% the same as above.

User control (ascx) in asp.net and its bindable properties dont show up in the data container

When I add a user control which has bindable properties to an asp.net page I do not see its bindable properties on the designer's dialog box when I click the edit Data bindings on the Repeater-Listview
should I add any other propery descriptors?
the markup would be like this inside a repeater or similar control
<uc1:Menu ID="Menu1" superman="<% Eval("userid") %>" runat="server" />
on the bindable property I only use
[System.ComponentModel.DefaultBindingProperty("superman")]
[System.ComponentModel.Bindable(true)]
public int superman
{
get;
set;
}
People discuss it here but they couldn't find a solution
I think this might be a problem with Visual Studio, I have not found a way to show the properties of user controls, but still, you can bind the property even when it does not appear in the options box:
This is how you bind it:
In the user control code behind:
[Bindable(true)]
public string MyProperty
{
get
{
return this.lblMessage.Text;
}
set
{
this.lblMessage.Text = value + DateTime.Now.ToString();
}
}
In the ASCX file:
<asp:Label ID="lblMessage" Text="something" runat="server" />
In the ASPX page:
<asp:DataList runat="server" ID="dataList" Width="50%"
DataSourceID="ObjectDataSource1">
<ItemTemplate>
<uc1:WebUserControl1 runat="server" ID="myUC" MyProperty='<%# Eval("Name") %>' />
</ItemTemplate>
</asp:DataList>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
SelectMethod="GetProducts" TypeName="WebApplication1.Repository">
</asp:ObjectDataSource>
Simple just add the property you created in your UC in the tag:
<uc1:WebUserControl1 runat="server" ID="myUC" MyProperty='<%# Eval("Name") %>' />
This is the output:
I think you just make the markup by typing it,
the user control must be drag and drop to the page in the design view.
try this may helps.

ASP.NET TreeView, select NodeTemplate upon databinding similar to the TemplateSelector in WPF?

Usage scenario,
I have hierarchically categorized items and I would like to present them in a TreeView. The TreeView will be populated on demand and it contains both the categories and the items, I would like to have different templates for the categories and the items. That is not a problem if the items were static I could easily list them in the aspx markup and specify template for each node, but on demand populating I have no clue how to do it. I don't mind any solution suggesting usage of Telerik TreeView or DevExpress Treeview.
Thanks in advanced.
Ok,
one day and no comment :), I got it done using RadTreeView, the RadTreeNode supports custom attributes, I added a custom attribute to distinguish between a category and an item, and in the NodeTemplate I used MultiView control which chooses the View to display by checking the node custom attribute.
Here is some parts of the code,
<telerik:RadTreeView ID="rtvQueries" runat="server" OnNodeExpand="rtvQueries_NodeExpand"
Skin="Black" OnClientNodeClicking="CheckNodeType" OnNodeClick="rtvQueries_NodeClick">
<NodeTemplate>
<asp:HiddenField ID="hfId" runat="server" Value='<%# Container.Value %>' />
<asp:MultiView ID="mvAll" runat="server" ActiveViewIndex='<%# Container.Attributes["ItemType"] == "C"? 0 : 1 %>'>
<asp:View ID="vwCategory" runat="server">
<asp:Label ID="lblCategory" runat="server" Text='<%# Container.Text %>' />
</asp:View>
<asp:View ID="vwQuery" runat="server">
<div style="float: left">
<asp:Label ID="lblQuery" runat="server" Text='<%# Container.Text %>' />
</div>
<div style="float: left; margin-left: 20px; overflow: hidden; width: 200px;">
<asp:Label ID="lblCommandText" runat="server" Text='<%# Container.Attributes["CommandText"] %>' />
</div>
</asp:View>
</asp:MultiView>
</NodeTemplate>
</telerik:RadTreeView>
The code-behind for NodeExpand,
protected void rtvQueries_NodeExpand(object sender, RadTreeNodeEventArgs e)
{
Guid categoryId = new Guid(e.Node.Value);
List<Category> cats = DBHelper.GetQueryCategories(categoryId);
cats.ForEach(c =>
{
RadTreeNode n = new RadTreeNode(c.Name, c.Id.ToString());
n.ExpandMode = TreeNodeExpandMode.ServerSideCallBack;
n.Attributes["ItemType"] = "C";
e.Node.Nodes.Add(n);
n.DataBind();
});
List<RightBI.Query> queries = DBHelper.GetQueriesByCategoryId(categoryId);
queries.ForEach(q =>
{
RadTreeNode n = new RadTreeNode(q.Name, q.Id.ToString());
n.Attributes["ItemType"] = "Q";
n.Attributes["CommandText"] = q.CommandText;
e.Node.Nodes.Add(n);
n.DataBind();
});
}
The only problem in this solution is I have to call DataBind on each node after adding it to the TreeView so the binding expressions evaluated.
I still would like to see other solutions and comments on this solution or better ideas.

Change the source of image by clicking thumbnail using updatePanel

For example, i have this ImageViewer.ascx UserControl:
<div class="ImageTumbnails">
<asp:ListView ID="ImageList" runat="server" ItemPlaceholderID="ItemContainer">
<LayoutTemplate>
<asp:PlaceHolder ID="ItemContainer" runat="server" />
</LayoutTemplate>
<ItemTemplate>
<asp:HyperLink runat="server"
NavigateUrl='<%# Link.ToProductImage(Eval("ImageFile").ToString())%>'>
<asp:Image runat="server" ImageUrl='<%# Link.ToThumbnail(Eval("ImageFile").ToString()) %>' />
</asp:HyperLink>
</ItemTemplate>
</asp:ListView>
</div>
<div class="ImageBig">
<asp:Image ID="ProductImageBig" runat="server" ImageUrl="" />
</div>
When the thumbnail is clicked it will change the source of ProductImageBig with its hyperlink target.
How can i achieve this using UpdatePanel ? ( Or will i be able to )
You are currently using a HyperLink control which will direct the user to the value of the NavigateUrl property. If it goes to a separate page, how will it modify the URL of the ProductImageBig control?
One option is to change the HyperLink control to a ImageButton and then specify a method in your codebehind for the "OnCommand" property.
In the code behind, you can cast the sender object to a the ImageButton, retrieve its ImageURL, and then set the URL of your ProductImageBig
public void DisplayPhoto(object sender, CommandEventArgs args)
{
ProductImageBig.NavigateUrl = ((ImageButton)sender).ImageUrl;
updatePanel.Update();
}
If you have the entire markup surrounded in an UpdatePanel named "updatePanel" and you have the properties set correctly, you can then update it after setting the Url.

Resources