Asp.NET Font-Size and service function - asp.net

i've the following code in aspx page
<asp:Label ID="CittaLabel" runat="server" Text='<%# Eval("Citta") %>' Font-Size='<%# ReturnFontSize(Eval("Big")) %>'/>
and this is my code behind service function
Protected Function ReturnFontSize(ByVal Big As Boolean) As FontUnit
If Big Then
ReturnFontSize = FontSize.Medium
Else
ReturnFontSize = FontSize.Small
End If
End Function
But i get always a font very very small.
So my question is : for changing "Font-Size" proprety of a control, from code behind, which return type i have to use, assuming that FontUnit not work ?
Thank you

You have to DataBind the Containercontrol of the label(f.e. a GridView or the complete page). Then you can call a Codebehind Function from the aspx-page.
Hence f.e. in Page-Load:
Me.DataBind()
and the function must return an object from type FontSize:
Protected Function ReturnFontSize(ByVal fontSize As Object) As FontSize
Select Case fontSize.ToString.ToUpper
Case "BIG"
Return WebControls.FontSize.Large
Case Else
Return WebControls.FontSize.Medium
End Select
End Function
and on aspx-page:
Font-Size='<%# ReturnFontSize(Eval("Big")) %>'
But why dont you set the Fontsize in Codebehind on Page.Load?
Me.CittaLabel.FontSize= ....

I find that performing Eval based property setting during a databinding event can often prove problematic unless you are binding to simple types such as strings and ints. It's generally easier and to simply perform your complex binding tasks during the code behind implementation of binding events such as the Repeater databind event.
Try the following instead, assuming you are using an ASP:Repeater control:
Markup:
<asp:Repeater runat="server" ID="rpt" OnDataBinding="rpt_OnDataBinding">
<ItemTemplate>
<asp:Label ID="CittaLabel" runat="server" Text='<%# Eval("Citta") %>' />
</li>
</ItemTemplate>
</asp:Repeater>
Code Behind:
protected void rpt_DataBinding(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
var data = (YourTypeThatIsDataBound)e.Item.DataItem;
var CittaLabel = (Label)e.Item.FindControl("CittaLabel");
CittaLabel.FontSize = ReturnFontSize(data.Big);
}
}
This way for every item being generated in your repeater you access the label in the server side databinding event and simply set the FontSize to be the output of your ReturnFontSize function that you have alread written. The only thing you have to do is cast the e.Item.DataItem object back to the original type of object the repeater was bound to and then pass its Big property into the function.

Related

Is it possible to use DataBinding to evaluate Controls on .aspx page?

I'm not sure if I am asking this question correctly. I know that I can accomplish what I need in code behind, but I'm wondering if this is possible. I want to hide a control if there is a value in another control. I know I can use databinder.eval in a repeater, but can I use it just for a normal asp control on the page?
In other words, I want to do something like this:
<asp:TextBox runat="server" ID="ConditionalText" Text="Show if other value is empty" Visible ='<%# testValue.Text != "" ? false : true %>'></asp:TextBox>
<asp:TextBox runat="server" ID="testValue"></asp:TextBox>
I tried just the way I have it above, and <%# testValue. exposed available properties of "testValue" TextBox so I thought it might work. It didn't throw any errors but it did not show/hide the textbox. I'm just wondering if this is possible and what I would have to do to accomplish this.
Any assistance is greatly appreciated.
It can work, but since you are using a databinding expression outside a GridView, Repeater etc. you have to call it manually.
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack == false)
{
//rest of the code
}
//call databind manually
DataBind();
}
PS better to use IsNullOrEmpty instead of = ""
<asp:TextBox runat="server" ID="ConditionalText" Text="Show if other value is empty"
Visible='<%# !string.IsNullOrEmpty(testValue.Text) ? false : true %>'></asp:TextBox>

DetailsView: How to set a HiddenField value using the CommandArgument on a New command?

I have inherited some code that has a GridView and a DetailsView in a webpart control.
The DetailsView is able to create two different kinds of an object e.g. TypeA and TypeB.
There's a dropdown list that filters the GridView by object type and the DetailsView has an automatically generated Insert button.
<asp:DetailsView ID="myDetailsView"
AutoGenerateInsertButton="True"
AutoGenerateEditButton="True"
AutoGenerateRows="false"
OnItemUpdating="OnItemUpdating"
DefaultMode="ReadOnly"
OnDataBound="OnDetailsViewBound"
OnItemInserting="OnItemInserting"
OnModeChanging="OnDetailsViewModeChanging"
runat="server">
I have been asked to:
remove the filter on the GridView; and
split the New buttons/links into two so there's a separate button for creating each type of object.
Removing the filter means that I need some other way to track what kind of object we're creating.
I have split the New links by changing the above to:
<asp:DetailsView ID="myDetailsView"
AutoGenerateInsertButton="False"
AutoGenerateEditButton="True"
AutoGenerateRows="false"
OnItemUpdating="OnItemUpdating"
DefaultMode="ReadOnly"
OnDataBound="OnDetailsViewBound"
OnItemInserting="OnItemInserting"
OnModeChanging="OnDetailsViewModeChanging"
runat="server">
and adding
<FooterTemplate>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton runat="server" ID="lnkCreateNewTypeA" CommandName="New" CommandArgument="TypeA" CssClass="buttonlink">New Type A</asp:LinkButton>
<asp:LinkButton runat="server" ID="lnkCreateNewTypeB" CommandName="New" CommandArgument="TypeB" CssClass="buttonlink">New Type B</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</FooterTemplate>
I haven't yet removed the filter so the changes currently function the same as before, as I'm using the New command.
What I was hoping to be able to do is somehow capture the New event so I can put the CommandArgument value into a hidden field, that the DetailsView would then use to determine which type of object it's creating and also to show/hide fields.
When I put breakpoints in all of the event handlers in my code, the first one to break is OnDetailsViewModeChanging, which doesn't have access to the CommandArgument.
OnItemCommand (if it's hooked up) is triggered when any button within the DetailsView is pressed and does give me access to the CommandArgument but I'm not sure what exactly needs to be done within this method to mimic the chain of events that occurs when you use automatically generated buttons.
Is my only option for retrieving the CommandArgument to capture it in the OnItemCommand event handler or is there some other event that is triggered on the New command?
Can anyone explain to me the sequence of events that occurs when the New command is triggered?
I read somewhere that it changes the mode to Insert but I don't know what else it does. I believe the OnItemInserting method isn't called until the "Insert" link is clicked.
Any help would be gratefully received!!
Edit:
I have found this link on DetailsView events but it hasn't answered my question.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.detailsview_events.aspx
Edit:
I have tried adding the following:
in ascx:
<asp:DetailsView ID="myDetailsView"
...
OnItemCommand="OnItemCommand"
...
runat="server">
...
<asp:TemplateField HeaderText="Object Type" HeaderStyle-CssClass="columnHeader">
<ItemTemplate>
<asp:HiddenField runat="server" ID="hidObjectType" Value=""/>
<asp:Label runat="server" ID="lblObjectType"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
in code behind:
protected void OnItemCommand(object sender, DetailsViewCommandEventArgs e)
{
if (e.CommandName.Equals("New"))
{
var objectType = e.CommandArgument.ToString();
HiddenField typeHidden = this.myDetailsView.FindControl("hidObjectType") as HiddenField;
if (typeHidden != null)
{
typeHidden.Value = objectType;
}
Label typeLabel = this.myDetailsView.FindControl("lblObjectType") as Label;
if (typeLabel != null)
{
typeLabel.Text = objectType;
}
}
}
I found that I didn't need to set the mode (this.myDetailsView.ChangeMode(DetailsViewMode.Insert);) in this method, as the OnDetailsViewModeChanging event handler still triggered.
This finds the controls and sets the values on them correctly. If I check the values again in OnDetailsViewModeChanging, their values are still set but as part of the logic in this method, there is a call to
this.myDetailsView.DataBind()
which causes a postback and at this point, the values are lost. I tried adding
EnableViewState="True"
but this made no difference. I've reviewed the page lifecycle (http://spazzarama.files.wordpress.com/2009/02/aspnet_page-control-life-cycle.pdf) and thought that maybe this.EnsureChildControls() would help but it's also made no difference.
An alternative would be to store the value in the session but I'd rather not.
As far as I can tell there is no event for capturing the "New" command aside from OnItemCommand, which captures all commands. (NOTE: You will need to make sure that CausesValidation="False" is set on your LinkButton or the code won't break into OnItemCommand).
When stepping through the code, the following occurred:
After the linkbutton was pressed, OnItemCommand is triggered. CommandName = "New" and here I could retrieve the CommandArgument
Next OnModeChanging is triggered. e.NewMode = "Insert". From all examples I've seen, here you call ChangeMode on the DetailsView and then call Databind() on it
Next OnDataBound is triggered as a result of calling Databind()
I didn't find a way to retain the value of the hidden variable between the various events so I ended up using a session variable. Code is below in case anyone wants it.
DetailsView declaration in the ASCX:
<asp:DetailsView ID="myDetailsView"
AutoGenerateInsertButton="False"
AutoGenerateEditButton="True"
AutoGenerateRows="false"
OnItemInserting="OnItemInserting"
OnItemUpdating="OnItemUpdating"
OnItemCommand="OnItemCommand"
DefaultMode="ReadOnly"
OnDataBound="OnDetailsViewBound"
OnModeChanging="OnDetailsViewModeChanging"
runat="server">
In the code-behind:
constant declarations...
private const string SESSIONKEY_MYVALUE = "MyValue";
private const string DEFAULT_OBJECTTYPE = "TypeA";
OnItemCommand event handler...
protected void OnItemCommand(object sender, DetailsViewCommandEventArgs e)
{
if (e.CommandName.Equals("New", StringComparison.InvariantCultureIgnoreCase))
{
var objectType = e.CommandArgument.ToString();
HiddenField typeHidden = this.myDetailsView.FindControl("hidObjectType") as HiddenField;
if (typeHidden != null)
{
typeHidden.Value = objectType;
}
HttpContext.Current.Session[SESSIONKEY_MYVALUE] = objectType;
}
}
OnModeChanging event handler....
protected void OnDetailsViewModeChanging(Object sender, DetailsViewModeEventArgs e)
{
if (e.NewMode == DetailsViewMode.Insert)
{
this.myDetailsView.ChangeMode(DetailsViewMode.Insert);
this.myDetailsView.DataBind();
}
}
OnDataBound event handler...
protected void OnDetailsViewBound(object sender, EventArgs e)
{
if (this.myDetailsView.CurrentMode == DetailsViewMode.Insert)
{
var sessionVar = HttpContext.Current.Session[SESSIONKEY_MYVALUE];
var objectType = sessionVar == null ?
DEFAULT_OBJECTTYPE :
sessionVar.ToString();
var typeHidden = this.myDetailsView.FindControl("hidObjectType") as HiddenField;
if (typeHidden != null)
{
typeHidden.Value = objectType;
}
}
}

Set Custom ASP.NET UserControl variables when its in a Repeater

<%# Register Src="~/Controls/PressFileDownload.ascx" TagName="pfd" TagPrefix="uc1" %>
<asp:Repeater id="Repeater1" runat="Server" OnItemDataBound="RPTLayer_OnItemDataBound">
<ItemTemplate>
<asp:Label ID="LBLHeader" Runat="server" Visible="false"></asp:Label>
<asp:Image ID="IMGThumb" Runat="server" Visible="false"></asp:Image>
<asp:Label ID="LBLBody" Runat="server" class="layerBody"></asp:Label>
<uc1:pfd ID="pfd1" runat="server" ShowContainerName="false" ParentContentTypeId="55" />
<asp:Literal ID="litLayerLinks" runat="server"></asp:Literal>
</ItemTemplate>
</asp:Repeater>
System.Web.UI.WebControls.Label lbl;
System.Web.UI.WebControls.Literal lit;
System.Web.UI.WebControls.Image img;
System.Web.UI.WebControls.HyperLink hl;
System.Web.UI.UserControl uc;
I need to set the ParentItemID variable for the uc1:pdf listed inside the repeater.
I thought I should be able to find uc by looking in the e.Item and then setting it somehow. I think this is the part where I'm missing something.
uc = (UserControl)e.Item.FindControl("pfd1");
if (uc != null) { uc.Attributes["ParentItemID"] = i.ItemID.ToString(); }
Any thoughts would be appreciated.
Also tried this with similar results... when I debug inside my usercontrol (pfd1) the parameters I am trying to set have not been set.
uc = (UserControl)e.Item.FindControl("pfd1");
if (uc != null)
{
uc.Attributes.Add("ContainerID", _cid.ToString());
uc.Attributes.Add("ParentItemId", i.ItemID.ToString());
}
UPDATE: It looks like my controls are not connected by a namespace. I've wrapped by the parent control (Layer) and the PressFileDownlad control in a namespace "MyControls". Also updated their Inherits reference on the aspx to read "MyControls.xxxxx". I'm able to type "MyControls.Layer" inside the code on layer.aspx.cs but I'm not able to get "MyControls.PressFileDownload"
If you implement ParentItemID as a public property in your user control, then you should be able to set it declaratively, e.g:
<asp:Repeater id="Repeater1" ...>
<ItemTemplate>
<uc1:pfd ID="pfd1" runat="server" ParentItemId='<%# Eval("ItemID") %>' ... />
Martin is right you should be able to set it in declarative way (in case your property is public) .
But your way should also work (just cast it properly)
((PressFileDownload)e.Item.FindControl("pfd1")).ParentItemId = 0;
The best way is to implement the OnDataBinding event for the user control. I try to stay away from putting code inline in the aspx using webforms if possible.
When the repeater gets bound, for each item that is bound, the OnDataBinding will fire for your user control and your handler can do what it needs. You don't have to go searching for the controls.
Here is an example:
// in your aspx
<uc1:pfd ID="pfd1" runat="server" ShowContainerName="false" ParentContentTypeId="55"
OnDataBinding="pfd1_DataBinding" />
// in your codebehind implement the OnDataBinding event
protected void pfd1_DataBinding(object sender, System.EventArgs e)
{
pfd uc = (pfd)(sender);
uc.ContainerID = _containerID.ToString();
uc.ParentItemID = Eval("ItemID");
// Here you can do more like access other items like hidden fields
// or cached objects or even other controls etc... Skys the limit.
}
EDIT: Notice from your comment you require more data than what is found in the datasource. In this case what I usually do is just make private member variables in the .cs that I store data in. So when you have the container ID just store it in a variable that will be accessible.
Eg in your .cs for your page:
public partial class _TestPage : System.Web.UI.Page
{
private int _containerID { get; set; }
Then when you load the data just set the _containerID property and it will be accessible in the OnDataBinding event. Just make sure you are binding after you have set the _containerID.

Add new row to database table from Datagrid

I am trying to update a database table from my datagrid using an event handler and ItemCommand. I manage to call the routine and everything is working fine except the text that is inserted into my database is empty. I managed to track this back to the text not being passed from my datagrids footer to the sql parameters. I tried using a string first and then passing that to the parameters but they were also empty. I am accessing the control using the following line.
sqlcmd.Parameters.Add("#GoodsDesc", SqlDbType.VarChar).Value = CType(e.Item.FindControl("txtGoodsDesc"), TextBox).Text
The control itself is defined using
<asp:TemplateColumn HeaderText="Goods Descriptions">
<ItemTemplate>
<asp:Label runat="server" ID="lblGoodsDesc" Text='<%# Eval("GoodsDesc") %>'></asp:Label>
</ItemTemplate>
<FooterTemplate>
<asp:TextBox ID="txtGoodsDesc" runat="server" TextMode="MultiLine" Rows="3"></asp:TextBox>
</FooterTemplate>
</asp:TemplateColumn>
Am I missing something here? It's like the text in the footer isnt being tied to the control before I call it.
HI Ryan, we will need more code then just that. Where are you .Add +ing this parameter in addition where is e.Item.FindControl what event is it?
You need to check if you are on the footer control:
protected void dg_ItemDataBound(object sender, DataGridItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Footer)
{
if (dg.EditItemIndex != -1)
{
((TextBox)e.Item.FindControl("txtGoodsDesc")).Text
}
}
}
Or in vb.net
if (e.Item.ItemType = ListItemType.Footer) then
Dim s as String=String.Empty
s=CType(e.Item.FindControl("txtGoodsDesc"), TextBox).Text
end if
So essentially I discovered that the issue that was occurring was that VB.Net was calling Page_Load before the event itself was being called, and in the Page_Load method I was calling the method that filled the datagrid, which cleared the textboxes in the footer before the values in them were being read.
To stop this I placed a condition around the call to the method in Page_Load
If Not IsPostBack Then
FillDataGrid()
End If
Then I called the FillDataGrid() function as the very last step in the handler, meaning that the data was read in and then the datagrid was bound to the new values.

Databind Function to Controls Visible Property Does Not Work

I'm using databinding to set the visible property on a control as such:
Control on Page:
<asp:LinkButton ID="ApproveTimeLink" runat="server" Visible="<%# CanApprove() %>"> Approve Time</asp:LinkButton>
Code on CodeBehind:
Protected bool CanApprove()
{
return false;
}
As you can see the control should not show, yet still does. I'm not getting any errors, and I'm baffled as to why this does not work.
Thanks for the help.
all you have to this is the following
protected void Page_Load(object sender, EventArgs e)
{
this.DataBind();
}
public bool CanApprove()
{
return false;
}
then you can use this method on the asp-control as you mentioned before!
but be we aware! Every property of the page has to be not null, otherwise the databind will fail with an exception!
Sometimes you cannot set control properties with <%# %> and you have to resort to using OnItemDataBound(...) to get a reference to the control and set its Visible property there. Another thing that sometimes can be an issue is nested quotes, but in your sample code I don't see that as a problem. If your real code includes nested quotes, like Visible="<%# CanApprove(Eval("ID"))%>" then that may be your real issue. You can get around this by using single quotes and alternating with double quotes.
This worked great for me too... thanks!!
<asp:Label runat="server" ID="lblLocaton" Text='<%# String.Format("{0}, {1}", Eval("City"), Eval("Region.Code")) %>' Visible="<%# ShowLocation() %>" />
AND
MfnPresenter.Website.Presenters.IInstituitonListView.ShowLocation
Get
End Get
Set(ByVal value As Boolean)
'Used by visibility binding expression on lblLocation control inside dlFinancialInsitution
End Set
End Property

Resources