Updating the UI Thread from within a loop: ASP.NET Webforms - c#

All,
I have an Update Panel control that contains a label control. I also have a Timer Control whose interval is set to 1 sec. The timer control is suppose to set the text of the label control every second with the value of a public property that changes after each iteration of the loop.
However the resulting functionality is that after the entire loop completes then the UI is updated. I'd like to know what would need to be done/coded to make sure the label control gets updated with the value of the _servername property after every iteration of the loop?
Heres my code:
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:Timer ID="tmr" runat="server" Interval="1000" ontick="tmr_Tick">
</asp:Timer>
<div>
<asp:UpdatePanel ID="udp1" runat="server" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="tmr" EventName="Tick" />
</Triggers>
<ContentTemplate>
<asp:Label ID="lblInserts" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdateProgress runat="server" ID="udprg1" AssociatedUpdatePanelID="udp1"
DisplayAfter="10">
<ProgressTemplate>
<img src="media/ajaxloaderBlueLoading.gif" alt="ProgressImage" />
</ProgressTemplate>
</asp:UpdateProgress>
<div id="_asyncCallsMadeDiv"></div>
</div>
</form>
//CODE BEHIND
public string ServerName
{
get { return _serverName; }
set { _serverName = value;}
}
protected void tmr_Tick(object sender, EventArgs e)
{
lblInserts.Text = ServerName;
}
protected void btnUpload_Click(object sender, EventArgs e)
{
//Loop through data
while((line = rdr.ReadLine()) != null)
{
string [] arrayline = line.Split(',');
ServerStatus s = new ServerStatus
{
ServerName = arrayline[0],
Purpose = arrayline[1],
Primary = arrayline[2],
Secondary = arrayline[3],
OS = arrayline[4],
MachineType = arrayline[5],
Comments = arrayline[6],
VMTools = arrayline[7],
TimeSettings = arrayline[8],
LastPatchDate = arrayline[9],
CARemoval = arrayline[10],
PLUpdate = arrayline[11],
DefaultGatewayChange = arrayline[12]
};
_serverName = arrayline[0];
}

The onTick property of your timer control is set to a method that doesn't exist. You can rename tmr_Tick method in your code behind to tmrUdp1_Tick or set the onTick property to tmr_Tick

Related

ASP.NET Timer do not work. How to call function every X seconds?

I am creating a page in ASP.NET Framework and I need to update text in Label every X seconds. I tried to create new Thread and call Thread.Sleep(), but it do not work, Everything what is written bellow Thread.Sleep do not execute, I do not know why. So I found on internet Timer. I created Timer and it do not call method. If I write it statically to .aspx it works:
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:Timer runat="server" id="UpdateTimer" interval="5000" ontick="UpdateTimer_Tick" />
<asp:UpdatePanel runat="server" id="TimedPanel" updatemode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger controlid="UpdateTimer" eventname="Tick" />
</Triggers>
<ContentTemplate>
<asp:Label runat="server" id="DateStampLabel" />
</ContentTemplate>
</asp:UpdatePanel>
protected void UpdateTimer_Tick(object sender, EventArgs e)
{
DateStampLabel.Text = DateTime.Now.ToString();
}
This works, but I want to change time, so I created it dynamically in C#:
if (!IsPostBack)
{
Timer timer = new Timer();
timer.Tick += UpdateTimer_Tick;
timer.Interval = 2000;
timer.Enabled = true;
}
But UpdateTimer has never been called. So I tried this and it still do not work:
protected override void OnInit(EventArgs e)
{
if (!IsPostBack)
{
Timer timeoutTimer = new Timer();
timeoutTimer.ID = "timeouttimer";
timeoutTimer.Interval = 10000;
timeoutTimer.Tick += new EventHandler<EventArgs>(UpdarteTimer_Tick);
UpdatePanel timerUpdatePanel = new UpdatePanel();
timerUpdatePanel.ContentTemplateContainer.Controls.Add(timeoutTimer);
ScriptManager.GetCurrent(this.Page).RegisterAsyncPostBackControl(timeoutTimer);
this.Page.Form.Controls.Add(timerUpdatePanel);
}
base.OnInit(e);
}
I really need this on my website. Please help me. How can I create some routine in ASP.NET? Why I can't use Thread.Sleep in website and why is my timer do not work? Thank you
If you just want to update the interval of the Timer on Page.. you can just reference the one already created and set the Interval in either Page_Init or Page_Load like this ...
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:Timer runat="server" id="UpdateTimer" interval="5000" ontick="UpdateTimer_Tick" />
<asp:UpdatePanel runat="server" id="TimedPanel" updatemode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger controlid="UpdateTimer" eventname="Tick" />
</Triggers>
<ContentTemplate>
<asp:Label runat="server" id="DateStampLabel" />
</ContentTemplate>
</asp:UpdatePanel>
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
UpdateTimer.Interval = 2000;
}
}
If it's ok, you can use js code
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<script type="text/javascript">
$(document).ready(function () {
setInterval(function () {
WebForm_GetElementById("MainContent_Label1").textContent = new Date().toLocaleString();
}, 1000);
});
</script>
Pay attention that Label ID and element name which you are looking for are different! (Honestly, I don't know why ASP.NET changes that ID)
After setting timer properties you have to call this line to start the timer:
timer.Start();
UPD:
I checked your UI timer and It works but It reload page every time when tick event happens.
<asp:Timer ID="Timer1" runat="server" OnTick="Timer1_Tick"></asp:Timer>
and in the code behind file:
protected void Page_Load(object sender, EventArgs e)
{
Timer1.Interval = 1000;
}
protected void Timer1_Tick(object sender, EventArgs e)
{
Label1.Text = DateTime.Now.ToString();
}
Thus, I recommend using js method which I mentioned in another answer.

Updatepanel resets progress bar to zero while refreshing

This is just the sample code which I am trying to achieve and it cannot be performed by Javascript.
Used an Updatepanel and trying to update the progress bar that it shows the progress while function is in execution
But when doing this, updatepanel starts from zero when it is refreshed
(It's not smooth continuous transition, rather it starts from zero and reaches to specified point everytime when timer-tick event occurs)
ASPX
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:Timer runat="server" ID="Timer1" Interval="1000" Enabled="False"
ontick="Timer1_Tick" />
<br />
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
</Triggers>
<ContentTemplate>
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" />
<br />
<br />
<div id="div3" runat="server" class="progress progress-danger progress-striped progress progress_sm active " style="width: 100%;">
<div id="e3" class="bar" runat="server" role="progressbar">
</div>
</div>
</ContentTemplate>
</asp:UpdatePanel>
JavaScript
var percentage;
function updateProgress2(percentage) {
var $bar1 = $("#e3");
//var $bar1 = $('.bar');
var pp = percentage + "%";
$bar1.width(pp);
$bar1.text(pp + "%");
}
C#
static int count2, i;
protected void Button1_Click(object sender, EventArgs e)
{
i=0;
count2=20;
Button1.Enabled = false;
Timer1.Enabled = true;
}
protected void Timer1_Tick(object sender, EventArgs e)
{
ScriptManager.RegisterStartupScript(this.Page, this.GetType(), "lol", "updateProgress2('" + count2 + "')", true);
i++;
count2 += 10;
if (count2 == 90)
{
Timer1.Enabled = false;
Button1.Enabled = true;
}
}
i want see your 'count2' property.
i can use this 'count2' property with session.
this code work correctly.
private int count2
{
get
{
if (Session["count2"] == null)
Session["count2"] = 0;
return int.Parse(Session["count2"].ToString());
}
set
{
Session["count2"] = value;
}
}

Updating CSS of Controls in different files via CodeBehind

I have this AJAX button that I want to update some CSS. The problem is that the controls I want it to update are in a different file and can't be moved out of that file.
This is the panel whose CSS I want to update, which is located in the Site.master file:
<asp:ScriptManager ID="ScriptManager" runat="server" />
<asp:UpdatePanel ID="Panel2" runat="server" updatemode="Always">
<ContentTemplate>
<div id="updateThis" runat="server"><p>Test text</p></div>
</ContentTemplate>
</asp:UpdatePanel>
This is the button, located in the Items.ascx file:
<asp:UpdateProgress runat="server" ID="PageUpdateProgress">
<ProgressTemplate>
<img class="ajax-loader" src="/Images/ajax-loader.gif" alt="Loading..." />
</ProgressTemplate>
</asp:UpdateProgress>
<asp:UpdatePanel ID="Panel3" runat="server" updatemode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger controlid="UpdateButton" eventname="Click" />
</Triggers>
<ContentTemplate>
<asp:Button runat="server" OnClick="UpdateButton"
OnClientClick="hideButton()" Text="Update"
class="update" ID="UpdateButton" name="UpdateButton"
type="submit" ></asp:Button>
</ContentTemplate>
</asp:UpdatePanel>
This is the Items.ascx.cs method that is UpdateButton
protected void UpdateButton(object sender, EventArgs e)
{
var masterPage = this.Page.Master;
var updatePanel = masterPage.FindControl("Panel2");
var div = (HtmlGenericControl)updatePanel.Controls[0].FindControl("updateThis");
div.Style.Add("color", "#ff0000");
}
When I click the button it doesn't end up working correctly. As of right now, with the AJAX UpdateProgress template, it shows the loading GIF and then the GIF disappears and the text never changes color.
EDIT
Hopefully this will give a better idea of where things might be going wrong:
THIS WORKS
protected void UpdateButton(object sender, EventArgs e)
{
var masterPage = this.Page.Master;
var updatePanel = masterPage.FindControl("Panel2");
var div = (HtmlGenericControl)updatePanel.FindControl("updateThis");
div.Style.Add("color", "#ff0000");
UpdateButton.Text = "Done!";
}
I had #updateThis in the FindControl() method. Don't be like me!
You should add the runat="server" attribute to the div control, to make it visible in code-behind:
<div id="updateThis" runat="server"><p>Test text</p></div>
You can also remove Controls[0] in the event handler (but it works if you keep it, according to my tests):
protected void UpdateButton(object sender, EventArgs e)
{
var masterPage = this.Page.Master;
var updatePanel = masterPage.FindControl("Panel2");
var div = (HtmlGenericControl)updatePanel.FindControl("updateThis");
div.Style.Add("color", "#ff0000");
}

Timer in ASP.Net (Language C#) stops after 1 tick

i wanted to use a timer in a program i'm working on, but it always stops after 1 tick !! can you give me any tips to make it repeat unstoppably (or until i want it to) please ??
this is my code:
int i = 20;
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = "(20)";
}
protected void Timer1_Tick(object sender, EventArgs e)
{
i--;
Label1.Text = "(" + i + ")";
if (i == 0)
{
Session["Profession"] = "Visiteur";
Response.Redirect("Acceuil.aspx");
}
Edit: my HTML code :
<form id="form1" runat="server">
<div><center>
<span class="style1">message</span><br
class="style1" />
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:Timer ID="Timer1" runat="server" Interval="1000" ontick="Timer1_Tick" >
</asp:Timer>
<asp:Timer ID="Timer2" runat="server" Interval="1000">
</asp:Timer>
<br />
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Label ID="Label1" runat="server"></asp:Label>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
</Triggers>
</asp:UpdatePanel>
<asp:LinkButton ID="LinkButton1" runat="server" onclick="LinkButton1_Click"
PostBackUrl="~/Acceuil.aspx">Retour</asp:LinkButton>
<br />
</center>
</div>
</form>
Edit2: what i want to do is the normal redirecting code, count to 20 and refreshing every second (to show to user how much secs left) and at the end it redirects to a new page, but it wasn't working, so i was wondering why ??
and i think i got my answer from #Andrei Rînea, and thank you everyone for your help : )
Edit3: Solved and here is the code :
static int i = 20;
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
Label1.Text = "20";
}
protected void Timer1_Tick(object sender, EventArgs e)
{
i--;
Label1.Text = i.ToString();
if (i == 0)
{
i = 20;
Session["Profession"] = "Visiteur";
Response.Redirect("Acceuil.aspx");
}
}
Thanks everyone again : )
Please use the following code :
static int i = 20;
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
Label1.Text = "(20)";
}
protected void Timer1_Tick(object sender, EventArgs e)
{
i--;
Label1.Text =i.ToString();
if (i == 0)
{
Session["Profession"] = "Visiteur";
Response.Redirect("Acceuil.aspx");
}
}
your HTML code should be like :
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<asp:Timer ID="Timer1" runat="server" ontick="Timer1_Tick" Interval="1000">
</asp:Timer>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
I'm going to assume here that you are wishing to have a process that ticks away on your server in the background.
I'm also going to assume you've tried to add this to your Webform.
If so, the issue you have encountered, is that your Webform object only exists for the short time that it is processing your request, after which it is disposed of - including your timer.
If I'm correct, you'd probably like to take a look at Quartz.Net:
http://www.mikesdotnetting.com/article/254/scheduled-tasks-in-asp-net-with-quartz-net
You are trying to run client side code on the server. You need to do this in JavaScript instead.
The C# code will be run just before rendering the page and not longer. You probably believe the code will run as long as the visitor is on the page which is not the case.

how add item from one listbox to another on web form

I have a two listboxes and a button. I need to add selected item from one listbox to another with click of button.
and here is the code of the button
protected void ASPxButton4_Click(object sender, EventArgs e)
{
if (listBoxSubeKiyaslama1.SelectedIndex > -1)
{
listBoxSubeKiyaslama2.Items.Add(listBoxSubeKiyaslama1.SelectedItem);
listBoxSubeKiyaslama2.Items.RemoveAt(listBoxSubeKiyaslama1.SelectedIndex);
listBoxSubeKiyaslama2.UnselectAll();
}
}
when I click the button, I see that listBoxSubeKiyaslama1.SelectedIndex is always "-1". because I think it postbacks and clears items from the first listbox. How can I fix this?
Can you try the below code:
if (listBoxSubeKiyaslama1.SelectedItem != null)
{
listBoxSubeKiyaslama2.Items.Add(listBoxSubeKiyaslama1.SelectedItem);
listBoxSubeKiyaslama2.Items.RemoveAt(listBoxSubeKiyaslama1.SelectedIndex);
listBoxSubeKiyaslama2.UnselectAll();
}
The controls will be not save the values on postbacks if EnableViewState = false. By default it is true. Please make sure you are not setting it to false.
I also suggest you to put your control in UpdatePanel to avoid full postback.
Like:
<asp:UpdatePanel ID="up1" runat="Server">
<ContentTemplate>
<asp:ListBox ID="listBoxSubeKiyaslama1" runat="server">
</asp:ListBox>
<asp:ListBox ID="listBoxSubeKiyaslama2" runat="server">
</asp:ListBox>
</ContentTemplate>
</asp:UpdatePanel>
Try the following code:-
ASPX.CS
public string GetSelectedItems(ListBox control)
{
var items = new StringBuilder();
foreach (ListItem item in control.Items)
{
if (item.Selected)
items.Append(string.Format("{0},", item.Value));
}
return items.ToString().Trim().TrimEnd(',');
}
protected void btnMoveRight_Click(object sender, EventArgs e)
{
for (int i = lbCourses1.Items.Count - 1; i >= 0; i--)
{
if (lbCourses1.Items[i].Selected == true)
{
lbCourses2.Items.Add(lbCourses1.Items[i]);
ListItem li = lbCourses1.Items[i];
lbCourses1.Items.Remove(li);
}
}
}
protected void btnMoveLeft_Click(object sender, EventArgs e)
{
for (int i = lbCourses2.Items.Count - 1; i >= 0; i--)
{
if (lbCourses2.Items[i].Selected == true)
{
lbCourses1.Items.Add(lbCourses2.Items[i]);
ListItem li = lbCourses2.Items[i];
lbCourses2.Items.Remove(li);
}
}
}
var selectedValues = GetSelectedItems(lb2);
ASPX
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<div>
<asp:Label ID="lbl1" runat="server" Text="lbl1:"></asp:Label>
<asp:ListBox ID="lb1" runat="server" SelectionMode="Multiple"></asp:ListBox>
<asp:Button Runat="server" ID="btnMoveRight" Text=">>"
onclick="btnMoveRight_Click"></asp:Button>
<asp:Button Runat="server" ID="btnMoveLeft" Text="<<"
onclick="btnMoveLeft_Click"></asp:Button>
<asp:ListBox ID="lb2" runat="server" SelectionMode="Multiple"></asp:ListBox>
</div>
</ContentTemplate>
</asp:UpdatePanel>

Categories

Resources