Inside usercontrol I have updatepanelanimationextender, when I add this control to a webpage I want to pass updatepanel's Id as parameter to control's property.
Usercontrol:
public partial class Controls_UpdateProgress : System.Web.UI.UserControl
{
public string UpdatePanelID { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
UpdatePanelAnimationExtender1.TargetControlID = UpdatePanelID;
}
}
}
<cc1:updatepanelanimationextender id="UpdatePanelAnimationExtender1" runat="server" >
<Animations>
<OnUpdating>
<Parallel duration="0" >
<ScriptAction Script="onUpdating();" />
</Parallel>
</OnUpdating>
<OnUpdated>
<Parallel duration="0">
<ScriptAction Script="onUpdated();" />
</Parallel>
</OnUpdated>
</Animations>
</cc1:updatepanelanimationextender>
WebPage: UpdatePanel1 is an id of the updatepanel.
<uc1:UpdateProgress ID="UpdateProgress1" runat="server" UpdatePanelID="UpdatePanel1" />
I get error:
The TargetControlID of
'UpdatePanelAnimationExtender1' is not
valid. The value cannot be null or
empty.
The AJAX control extenders do not store their TargetControlID in the ViewState (I checked in System.Web.Extensions 3.5 with Reflector and that property only gets/sets a private member). Thus, the value you stored is lost on postback.
You'll have to store the value in every request:
protected void Page_Load(object sender, EventArgs e)
{
UpdatePanelAnimationExtender1.TargetControlID = UpdatePanelID;
}
To avoid that exception, you should first make sure that UpdatePanelID is not null...
if (!IsPostBack) {
if (UpdatePanelID != Null) {
UpdatePanelAnimationExtender1.TargetControlID = UpdatePanelID;
}
}
If you desire to set the property of the UpdatePanelID from the parent page programmatically you will need to cast UpdateProgress1 as a Controls_UpdateProgress instance. To do that, do something like this...
((Controls_UpdateProgress)UpdateProgress1).UpdatePanelID = "ThisIsTheIdYouWishToSet";
Related
I'm trying to make a really simple grid for some data on an ASP.NET page, but clearly I'm doing something wrong here. First of all, let me show you the grid I have on my clientside:
<asp:Panel runat="server" ID="pnlDoorAccess" Visible="False">
<asp:UpdatePanel runat="server" ID="upnlDoorAccess" UpdateMode="Conditional" ChildrenAsTriggers="false">
<ContentTemplate>
<tel:RadGrid runat="server" ID="gvDoorAccess" AllowSorting="false" AllowPaging="false"
CssClass="col-sm-12 noPadding" MasterTableView-CssClass="table table-hover table-header-bg table-striped no-footer tableHeaderBorder"
OnNeedDataSource="radDoorAccess_NeedDataSource" OnItemDataBound="radDoorAccess_ItemDataBound">
<MasterTableView AutoGenerateColumns="false" TableLayout="Fixed" Caption="" FilterExpression="" AllowNaturalSort="false" DataKeyNames="Month" NoMasterRecordsText="No records to Display">
<Columns>
<tel:GridBoundColumn DataField="DoorName" HeaderText="Door Name" UniqueName="DoorName"></tel:GridBoundColumn>
</Columns>
</MasterTableView>
</tel:RadGrid>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Panel>
So I wanna test the grid by only showing 1 column (DoorName), but so far it's not showing anything. Next is the server side code:
The DoorAccess property will fire up Controller.GetDoorAccess(CurrentUser.Id) when the Object Memorystore is empty and return me a DataTable object which I will return and eventually store into a DataSource property later on.
protected List<DoorAccess> DoorAccess
{
get
{
if (omsDoorAccess.DataItem == null || omsDoorAccess.DataItem.GetType() != typeof(List<Option>)) omsDoorAccess.DataItem = Controller.GetDoorAccess(CurrentUser.Id);
return (omsDoorAccess.DataItem as List<DoorAccess>);
}
set
{
omsDoorAccess.DataItem = value;
}
}
protected void Page_Load(Object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
LoadTab_DoorAccess();
}
}
private void LoadTab_DoorAccess()
{
// Future implementation
ReloadTab_DoorAccess();
}
private void ReloadTab_DoorAccess()
{
gvDoorAccess.DataBind();
upnlDoorAccess.DataBind();
upnlDoorAccess.Update();
}
protected void radDoorAccess_NeedDataSource(object sender, GridNeedDataSourceEventArgs e)
{
(sender as RadGrid).DataSource = DoorAccess;
// DoorAccess holds 128 items
}
protected void radDoorAccess_ItemDataBound(object sender, GridItemEventArgs e)
{
if (e.Item.ItemType != GridItemType.Item && e.Item.ItemType != GridItemType.AlternatingItem)
{
// Do stuff in the future
}
}
So what exactly is going on here? There is probably something obvious I'm missing, but right now I don't see it.
If this question makes no sense, could you show me a block of code that would help me create a simple grid?
I see that you have AutoGeneratedColumns="False", a single column declared with the DataField="DoorName", and DataKeyName="Month".
When using Advanced DataBinding the datasource you are binding to must match the schema in the RadGrid unless you are using AutoGenerateColumns.
Without seeing your controller code, I think the issue is with the above Markup. There is no way for the grid to bind the single column with the DataField of "DoorName" to the DoorAccess object using the DataKeyName of "Month"(not knowing where "Month" is coming from). Make sure the DataKeyName property contains a unique value from the DoorAccess object and that the column DataField is equal to any property in the DoorAccess object.
ASPX:
<telerik:RadGrid ID="RadGrid1" runat="server" OnNeedDataSource="RadGrid1_NeedDataSource">
<MasterTableView AutoGenerateColumns="False" DataKeyNames="Id" CommandItemDisplay="Top">
<Columns>
<telerik:GridBoundColumn DataField="Id" UniqueName="MyId" HeaderText="My Id"></telerik:GridBoundColumn>
<telerik:GridBoundColumn DataField="Value" UniqueName="Value" HeaderText="My Value"></telerik:GridBoundColumn>
</Columns>
</MasterTableView>
</telerik:RadGrid>
C#:
public class MyDataModel
{
public int Id { get; set; }
public string Value { get; set; }
}
protected void RadGrid1_NeedDataSource(object sender, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
{
List<MyDataModel> datasource = new List<MyDataModel>();
for (i = 0; i <= 10; i++) {
datasource.Add(new MyDataModel {
Id = i,
Value = "Value" + i.ToString
});
}
((RadGrid)sender).DataSource = datasource;
}
I would first try with autogenerated columns on to make sure valid data is being returned from the NeedDataSource event, and then make sure your DataKeyNames and DataFields are valid properties. Additionally as #Seano666 said, because your grid is in an UpdatePanel any errors the RadGrid throws due to incorrect formatting will be suppressed.
I have got 10 button/Links in aspx page. I need to maintain a session variable on only ONE button click and for all other 9 click/action I need to change the value in session variable.
How can I get this in a best way, instead of writing in those 9 click actions.
Please suggest
You can re-use the same event for multiple buttons, and check the 'sender' to see which button was clicked.
Markup:
<asp:Button ID="Button1" runat="server" OnClick="GenericButtonClick" Text="Button" />
<asp:Button ID="Button2" runat="server" OnClick="GenericButtonClick" Text="Button" />
CS:
protected void GenericButtonClick(object sender, EventArgs e)
{
Button button = sender as Button;
switch(button.ID)
{
case "Button1":
//Maintain Session Variable
break;
default:
//Change Value in Session Variable
break;
}
}
You then set all your buttons to use the same event handler
I use mostly the command event handler instead of click, so in aspx side, you would have something like this:
<asp:Button ID="Button1" runat="server" OnCommand="DoSomething" CommandName="SetSession" CommandArgument="true" />
<asp:Button ID="Button2" runat="server" OnCommand="DoSomething" CommandName="SetSession" CommandArgument="false" />
<asp:Button ID="Button3" runat="server" OnCommand="DoSomething" CommandName="SetSession" CommandArgument="false" />
And in the back end cs file, there would be only one event handler like this:
protected void DoSomething(object sender, CommandEventArgs e)
{
if (e.CommandArgument.ToString() == "true")
{
// set session
}
}
The benefit of using CommandEventHandler is that even later on you change the button to ImageButton or LinkButton, you don't need to change the event signature, it works for all.
You can make a property in which you can set the session value and you can also get value from this property. I have made it private because it is used only in that page where you need.
private static string SetGetSession
{
set { HttpContext.Current.Session["Mairaj"] = value; }
get { return HttpContext.Current.Session["Mairaj"].ToString(); }
}
Here is how you can use it
protected void btnOne_Click(object sender, EventArgs e)
{
SetGetSession = "Mairaj";
}
protected void btnTwo_Click(object sender, EventArgs e)
{
SetGetSession = "Ahmad";
}
protected void btnTh_Click(object sender, EventArgs e)
{
SetGetSession = "Minhas";
}
If you want it to be used in other pages as well you can make a class and make this property public you will be able to access it everywhere.
What I am trying to achieve that if a user control already added to placeholder then it will be removed otherwise will be added to it and it will be done in a LinkButton's onclick.
The code:
public partial class SiteSettings : System.Web.UI.Page {
private UserSettings UserSettingsControl;
protected void Page_Load(object sender, EventArgs e) {
System.Diagnostics.Debug.WriteLine("Pageload");
UserSettingsControl = LoadControl("~/UserControls/UserSettings.ascx") as UserSettings;
}
protected void UserLink_Click(object sender, EventArgs e) {
if (SettingsPlaceholder.Controls.Contains(UserSettingsControl)) {
System.Diagnostics.Debug.WriteLine("Contains");
SettingsPlaceholder.Controls.Remove(UserSettingsControl);
} else {
System.Diagnostics.Debug.WriteLine("Does not Contains");
SettingsPlaceholder.Controls.Add(UserSettingsControl);
}
}
}
Now it is not working. And I am getting:
Pageload // on first time load
Pageload // on first time click
Does not Contains // on first time click
Pageload // on second time click
Does not Contains // on second time click
in the Output window.
How can I achieve this? I also tried to store it into ViewState, but since UserControl is not serializable so that didn't worked.
The aspx page is:
<telerik:RadAjaxManager ID="AjaxManager" runat="server">
<AjaxSettings>
<telerik:AjaxSetting AjaxControlID="UserLink">
<UpdatedControls>
<telerik:AjaxUpdatedControl ControlID="SettingsPanel" LoadingPanelID="LoadingPanel" UpdatePanelRenderMode="Block" />
<telerik:AjaxUpdatedControl ControlID="PlaceHolderPanel" />
</UpdatedControls>
</telerik:AjaxSetting>
</AjaxSettings>
<ClientEvents OnResponseEnd="respondEnd" />
</telerik:RadAjaxManager>
<asp:Panel ID="SettingsPanel" runat="server">
<telerik:RadSplitter ID="MainSplitter" runat="server" MinHeight="200" Width="100%"
OnClientLoaded="splitterLoaded" OnClientResized="splitterLoaded">
<telerik:RadPane ID="LeftPane" runat="server" MaxWidth="250" Width="150" MinWidth="150" CssClass="left-rounded-corner settings-splitter-left">
<asp:Panel runat="server">
<asp:LinkButton ID="UserLink" runat="server" onclick="UserLink_Click" Text="User Settings" />
</asp:Panel>
</telerik:RadPane>
<telerik:RadSplitBar ID="Splitbar" runat="server" CollapseMode="Forward" />
<telerik:RadPane ID="RightPane" runat="server" CssClass="right-rounded-corner settings-splitter-right">
<asp:Panel ID="PlaceHolderPanel" runat="server" Height="100%">
<asp:PlaceHolder runat="server" ID="SettingsPlaceholder" />
</asp:Panel>
</telerik:RadPane>
</telerik:RadSplitter>
</asp:Panel>
<telerik:RadAjaxLoadingPanel ID="LoadingPanel" runat="server" />
Edit:
Modified code:
public partial class SiteSettings : System.Web.UI.Page {
protected void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) {
AddUserSettings();
}
}
public UserControl UserSettingsControl {
get {
if (ViewState["UserSettings"] == null) {
ViewState["UserSettings"] = LoadControl("~/UserControls/UserSettings.ascx") as UserSettings;
}
return (UserControl)ViewState["UserSettings"];
}
}
public UserControl SpaceSettingsControl {
get {
if (ViewState["SpaceSettings"] == null) {
ViewState["SpaceSettings"] = LoadControl("~/UserControls/SpaceSettings.ascx") as SpaceSettings;
}
return (UserControl)ViewState["SpaceSettings"];
}
}
protected void SettingsLink_OnCommand(object sender, CommandEventArgs commandEventArgs) {
switch (commandEventArgs.CommandName) {
case "User":
AddUserSettings();
break;
case "Space":
AddSpaceSettings();
break;
}
}
private void AddUserSettings() {
AddSettings(UserSettingsControl);
}
private void AddSpaceSettings() {
AddSettings(SpaceSettingsControl);
}
private void AddSettings(UserControl control) {
SettingsPlaceholder.Controls.Add(control);
}
}
Create a Property in your WebForm like below.
public UserSettings UserSettingsControl
{
get
{
if (Session["MyControl"] == null)
Session["MyControl"] =
LoadControl("~/UserControls/UserSettings.ascx") as UserSettings;
return (UserSettings)Session["MyControl"];
}
}
Now you can access the memory of UserSettingsControl. As it will persist across the Postback. In the original code, the UserSettingsControl was being reset to null across PostBack.
By end of the Page Life Cycle all the controls created at runtime
will be disposed. Finally, you cannot find the control created at
runtime after Postback. Only Recreation of the same control will be
required on each PostBack.
You could just not use a PlaceHolder and have the control there the whole time. Then the linkButton could toggle the visibility of the control.
The main problem is that the you are adding the control to the page linkButton click. Dynamically added controls work best when added in the Page_Init and Page_PreInit this allows them to maintain their ViewState. Also they have to be added to the placeholder on every postback. If in your example another control causes a postback after the SettingsControl is added to the placeholder, then the SettingsControl will disappear because it is not being added on every postback.
I have a ListView that has a FileUpload control and a button in each ListViewItem.
I have an OnClick event on my button where i try and pull information from the FileUpload control, but when I try to access the control all of the values that were set are gone (FileName etc).
What do I need to do differently here to access the information I just entered?
<asp:ListView ID="lv_Uploads" runat="server" OnItemDataBound="GetThumbs" EnableViewState="true" >
<LayoutTemplate>
<div id="itemPlaceholder" runat="server" />
</LayoutTemplate>
<ItemTemplate>
<div style="width:500px;>
<asp:FileUpload runat="server" ID="fu_Upload" />
<asp:Button ID="btn_Save" runat="server" Text="Save File" OnClick="SaveFile" />
<br />
</div>
</ItemTemplate>
</asp:ListView>
Code behind:
protected void SaveFile(object sender, EventArgs e)
{
//This always evaluates to an empty string...
string myFile = ((FileUpload)((Button)sender).Parent.FindControl("fu_Upload")).FileName;
}
I tested the code you provided for the aspx and the following as the code behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
lv_Uploads.DataSource = data;
lv_Uploads.DataBind();
}
}
protected void SaveFile(object sender, EventArgs e)
{
//This always evaluates to an empty string...
string myFile = ((FileUpload)((Button)sender).Parent.FindControl("fu_Upload")).FileName;
}
protected void GetThumbs(object sender, ListViewItemEventArgs e)
{
}
protected IEnumerable<string> data = new string[] { "test1", "test2", "test3" };
The FileUpload control had data for me on PostBack.
Are you using an UpdatePanel around the ListView? FileUpload controls are not compatible with UpdatePanels.
See:
FileUpload control inside an UpdatePanel without refreshing the whole page?
and
http://msdn.microsoft.com/en-us/library/bb386454.aspx#UpdatePanelCompatibleControls
Is the ListView control being rebound before SaveFile is fired on PostBack? If so, it would wipe out any values the user entered.
I am using a UserControl Which is present in the Master Page. I need to access a Master page control in the UserControl. I need your suggestions.
The Scenario is A label is present in the Master Page. Based upon selections in the usercontrol i need to modify the masterpage label. The UserControl is present in the Master page itself not in the content place holder.
Create a public method (or public property) in the master page to modify your label and in the UserControl you are able to call it, through the Page.master object:
YourMasterPageClass master = Page.master as YourMasterPageClass;
if(master != null)
{
master.YourEditMethod("hello");
}
Quick and Easy way is to create event in control and handle in master like this:
//Control aspx
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="TestControl.ascx.cs"
Inherits="TestControl" %>
<div style="width:300px;border:2px groove blue;">
<asp:Button ID="btn1" runat="server" Text="One" onclick="btn_Click" />
<asp:Button ID="btn2" runat="server" Text="Two" onclick="btn_Click" />
<asp:Button ID="btn3" runat="server" Text="Three" onclick="btn_Click" />
<asp:Button ID="btn4" runat="server" Text="Four" onclick="btn_Click" />
</div>
//Control C#
namespace Controls
{
public partial class TestControl : System.Web.UI.UserControl
{
public delegate void UserChoice(TestEventArgs e);
public event UserChoice OnUserChoice;
protected void btn_Click(object sender, EventArgs e)
{
if (OnUserChoice != null)
OnUserChoice(new TestEventArgs(((Button)sender).Text));
}
}
public class TestEventArgs : EventArgs
{
private string _value;
public TestEventArgs(string str)
{
_value = str;
}
public string Message
{
get { return _value; }
}
}
}
//MasterPage Code
protected void Page_Load(object sender, EventArgs e)
{
test1.OnUserChoice += new
Controls.TestControl.UserChoice(test1_OnUserChoice);
}
void test1_OnUserChoice(ROMS.Intranet.Controls.TestEventArgs e)
{
MasterLabel.Text = e.Message;
}
MasterLabel is name of the label in master page.
test1 is the control in master page.