I am trying to develop a chat using aspx. I already got it working with asmx + winform but now I have problems with asmx + aspx.
Basically what I want to do is call the WebMethod CheckForMessages every two seconds and, if there are messages, add them to a list box inside an update panel and do UpdatePanel1.Update();.
The problem is that apparently I can' t do this using a thread like I do in my winform.
void check() {
while (true) {
Thread.Sleep(2000);
string message = CheckForMessages();
if (message != "") {
ListBox1.Items.Add(message);
UpdatePanel1.Update();
}
}
}
I start the thread like this:
protected void Page_Load(object sender, EventArgs e) {
timer = new Thread(new ThreadStart(check));
timer.Start();
}
It doesn't throw an exception or anything, the program runs as intended. The web service is called, a string is returned if there is a message, the thread adds the message to the list and calls UpdatePanel1.Update();. Yet the panel is not updated.
What could the problem be ?
In ASP.Net you can use timer control along with updatepanel.
<asp:UpdatePanel runat="server" ID="uxUpdatePanel" UpdateMode="Conditional" EnableViewState="true">
<ContentTemplate>
<div>
<asp:Label ID="Label1" runat="server" style="display:none;"><%=GetMessageLog()%></asp:Label>
<asp:ListBox runat="server" ID="ListBox1" EnableViewState="true">
</asp:ListBox>
</div>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="uxTimer" EventName="Tick" />
</Triggers>
</asp:UpdatePanel>
<asp:Timer runat="server" ID="uxTimer" Interval="2000">
</asp:Timer>
And in Code-behind you to code like:
public string GetMessageLog()
{
string message = CheckForMessages();
if (message != "") {
ListBox1.Items.Add(message);
return DateTime.Now.ToLongTimeString();
}
This should work for you. But I will recommend you to use Javascript and JQuery to call Web-Service asynchronously with setTimeout function.
Instead of the server actively pushing changes to the client, try the opposite : make the client actively query the server, and update its state accordingly.
One way to do that is create a button to query the server manually. After you verify that it works, make the button hidden using css, and set a function to click the button in a regular interval. You can use javascript setInterval for this.
To click a button in javascript, you can do something like this :
setInterval(function(){ document.getElmtById(“<%= theButton.ClientID %>").click(); }, 2000);
The above code should click theButton every 2 seconds.
You should have a look at SignalR.net. Jabbr.net is based on signalR and exactly what you need. https://github.com/davidfowl/JabbR
yes Vishal... maybe less complex:
<asp:UpdatePanel ID="updatePanelPromptB" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Label ID="labelPlayback" runat="server"></asp:Label>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="timerPromptB" EventName="Tick" />
</Triggers>
</asp:UpdatePanel>
<asp:Timer runat="server" ID="timerPromptB" OnTick="timerPromptB_Tick" Enabled="false" Interval="4000" />
private void promptBottom(string text)
{
labelPlayback.Text = text;
updatePanelPromptB.Update();
timerPromptB.Enabled = true;
}
protected void timerPromptB_Tick(object sender, EventArgs e)
{
labelPlayback.Text = "OK";
timerPromptB.Enabled = false;
}
Related
i am trying to rebind my Dropdown upon button click, in particular if Block but it doesn't rebind, i mean that it should reload the drop down, kinda refresh and first item should be selected, i am doing this but not getting rebinded
Code:(It si inside buttong click event)
if (NotAssignedConductors.Length > 0)
{
string[] NotAssignedConductorsArray = NotAssignedConductors.Split(':');
foreach (string str in NotAssignedConductorsArray)
{
ResultLabel.ResultLabelAttributes(str, ProjectUserControls.Enums.ResultLabel_Color.Red);
}
FillDropDownListDevices();
}
Method being called:
public void FillDropDownListDevices()
{
DropDownListDevices.DataSource = ManageTransport.ManageConductorDevices.GetDevices();
DropDownListDevices.DataTextField = "TerminalSNO";
DropDownListDevices.DataValueField = "DeviceID";
DropDownListDevices.DataBind();
DropDownListDevices.Items.Insert(0, new ListItem("None", "-1"));
}
Button:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:DropDownList ID="DropDownListDevices" AutoPostBack="true" runat="server" OnSelectedIndexChanged="DropDownListDevices_SelectedIndexChanged" CssClass="form-control">
</asp:DropDownList>
<ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnCreate" EventName="click" />
</Triggers>
</asp:updatePanel>
There are many possibilities
If you are using update panel make sure you trigger update-panel to update on button click
check your page_load/page_loadComplete event and make sure you are not binding drop-down again .
check your browser console it throws any error on button click?
Create Post back trigger on update panel
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:DropDownList ID="DropDownListDevices" AutoPostBack="true" runat="server" OnSelectedIndexChanged="DropDownListDevices_SelectedIndexChanged" CssClass="form-control">
</asp:DropDownList>
<ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" />
</Triggers>
</asp:updatePanel>
Put your first time binding method on Postback
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//means no postback..page loaded first time
// Put your first time Binding method here
}
}
I'm in need of a synchronous call from code-behind ASP.NET (C#) to a Javascript function.
I've tried the ScriptManager.Registerclient, but as this is asynchronous this is no good. I'm in need of some testing in javascript before returning a value (updating an UpdatePanel) to check whether or not the operation is valid.
For a short code example:
myButton_click(object sender, EventArgs args)
{
<callJavascriptSynchronous>
if (MyHiddenField.Value == "true")
//Do
else
//Don't
}
MyHiddenField is within an UpdatePanel. For the javascript function:
function javascriptFoo(myInteger)
{
var returnValue = window.external.TestInteger(myInteger);
document.getElementById('<%=MyHiddenField.ClientID%>').value = returnValue;
}
The UpdatePanel looks like this:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:HiddenField ID="MyHiddenField" runat="server" ClientIDMode="Static" Value="" Visible="false"/>
</ContentTemplate>
Any suggestions on the synchronous call?
Thanks!
Edit: Added full code:
MyPage.aspx:
function javascriptFoo(myInteger)
{
var returnValue = window.external.TestInteger(myInteger);
document.getElementById('<%=MyHiddenField.ClientID%>').value = returnValue;
}
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:HiddenField ID="MyHiddenField" runat="server" ClientIDMode="Static" Value="" Visible="false"/>
</ContentTemplate>
<asp:GridView ID="GridView1" runat="server" OnRowCommand="GridView1_RowCommand">
MyPage.aspx.cs:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
ScriptManager.RegisterStartupScript(UpdatePanelContext, UpdatePanelContext.GetType(), "AlertTest", "AlertTest()", true);
string sVal = HiddenFieldContext.Value;
if (sVal == "true") //do
else //don't
}
When you're in your button's click-event, you've already left the frontend and cannot jump back for a function call. Execute the function first, clientside, upon the button-click (read about the OnClientClick event), then return your result with the postback.
This link addresses the same issue.
I have spent lot of time to investigate how to update label outside Update panel. And finally found something but it does not update label. It works fine if we refresh the page. Please let me know error in code or any new way of doing this. Please find my code below. I think need add some more code for script manager Or dataItem()
Thank you guys for reply!
Code behind file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class scriptMgr : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void timer_Tick(object sender, EventArgs e)
{
if (ScriptManager1.IsInAsyncPostBack)
{
ScriptManager1.RegisterDataItem(Label3, "Hi");
}
}
}
}
Aspx page
<div>
<asp:Label ID="Label3" runat="server" Text="krwelkr"></asp:Label>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<script type="text/javascript" language="javascript">
enter code here
Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(PageLoadingHandler);
function PageLoadingHandler(sender, args) {
var dataItems = args.get_dataItems();
if ($get('Label3') != null)
$get('Label3').innerHTML = dataItems['Label3'];
}
</script>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer" EventName="Tick" />
</Triggers>
</asp:UpdatePanel>
</div>
If you need to update the label with dynamic content from the server, have it wrapped in the same updatepanel or another updatepanel.
If the Label text is not dynamic, you could probably use JS to alter the label before firing the right event.
Also, UpdatePanels do "cause postbacks". its just that you don't notice them.
Or you can do this way:
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode=Conditional>
<ContentTemplate>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdatePanel ID="UpdatePanel2" runat="server">
<ContentTemplate>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" />
</ContentTemplate>
</asp:UpdatePanel>
Code-behind:
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = "Updated";
}
You need to use the pageLoaded event of the PageRequestManager.
The pageLoading event is raised before any content on the page is updated. So your changes made in pageLoading event will be lost if you also make changes to label's content anywhere else.
Therefore, when using the pageLoaded event which is raised after all content on the page is refreshed as a result of either a synchronous or an asynchronous postback, chnages made inside this event will overwrite all changes made anywhere else and will be the final.
<script type="text/javascript" language="javascript">
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(PageLoadedHandler)
function PageLoadedHandler(sender, args) {
var dataItems = args.get_dataItems();
if ($get('Label3') != null)
// set Label3 to your actual values. You can test/debug by adding
// any test value
$get('Label3').innerHTML = "TTTTestingggg";
}
</script>
Add the register script in code behind event,
protected void timer_Tick(object sender, EventArgs e)
{
if (ScriptManager1.IsInAsyncPostBack)
{
//ScriptManager1.RegisterDataItem(Label3, "Hi");
ScriptManager.RegisterStartupScript(this, this.GetType(), "setLabelOrAnyName", "jQuery(function($) { $('#Label3').text('Whatever')});", true);
}
}
This should work.
Incase if you are not using jQuery library replace code with simple javascript.
i have same problem as this question.se the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation i havent any problem with <%# Page EnableEventValidation="false" %>.I solve it and i try
protected void Timer1_Tick(object sender, EventArgs e)
{
Label2.Text = Convert.ToString((Convert.ToInt32(Label2.Text) - 1));
if (Convert.ToInt32(Label2.Text) == 0)
{
Timer1.Dispose();
Submit();
}
}
Code work fine means submit () is work if i call from submit button.If its call from Timer_Tick its not work.And timer is not stop or dispose.What is a problem plz suggest?
timer:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Timer ID="Timer1" runat="server" Interval="1000" ontick="Timer1_Tick">
</asp:Timer>
<asp:Label ID="Label1" runat="server" Text="Remaining Time:(Min)"></asp:Label>
<asp:Label ID="Label2" runat="server" Text="100"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
where are you Enabling or Starting the timer on the page? The timer will not automatically start upon page load, you will need to explicitly call Start() or set Enabled = true
Label2.Text = Convert.ToString((Convert.ToInt32(Label2.Text) - 1));
Does that line works?
Maybe the if
Convert.ToInt32(Label2.Text) == 0
doesn't return true
Being new to ASP.NET I have run into trouble building my own Whack-a-mole program. I think my problem comes from using Buttons, which by themselves send post backs to the server, making the software unusable. The looks are in place, making new buttons show up in the grid, in different places by random. However, when a button is pushed – the score doesn’t change (which I feel is strange).
Not so strange is that the Button doesn’t work since it sends post back to the server – reloading the UpdatePanel. I think I should use a different controller like the CheckBox and style it hard using CSS (which isn’t a problem). Is this the correct way to go, or should I make use of JavaScript AJAX instead?
Note to self: This technique shouldn’t be used in a public application since it put too much unwanted pressure on the web server. Use in test and learning only!
Thanx for listening!
<%# Page Language="C#" MasterPageFile="~/MasterPage.master"
AutoEventWireup="true" CodeFile="Whack-a-mole.aspx.cs"
Inherits="Whack_a_mole" %>
<asp:Content ID="Content" ContentPlaceHolderID="cphContent" runat="server">
<h1>Whack-a-Mole</h1>
<asp:ScriptManager ID="smgrTime" runat="server" />
<asp:Timer ID="Timer" OnTick="Timer_Tick" runat="server" Interval="2000" />
<asp:UpdatePanel ID="updpButtons" runat="server" UpdateMode="Always">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer" />
</Triggers>
<ContentTemplate>
<asp:Label ID="lblPoints" runat="server" Text="Score: 0p" />
<asp:Button ID="Button1" runat="server" BorderStyle="Outset"
BorderWidth="3px" CssClass="mole" Text="Mole"
onclick="Button1_Click" />
<asp:Button ID="Button2" runat="server" BorderStyle="Outset"
BorderWidth="3px" CssClass="mole" Text="Mole"
onclick="Button2_Click" />
<asp:Button ID="Button3" runat="server" BorderStyle="Outset"
BorderWidth="3px" CssClass="mole" Text="Mole"
onclick="Button3_Click" />
<!-- continues the same way down to Button25 -->
<asp:Button ID="Button25" runat="server" BorderStyle="Outset"
BorderWidth="3px" CssClass="mole" Text="Mole"
onclick="Button25_Click" />
</ContentTemplate>
</asp:UpdatePanel>
</asp:Content>
Excerpt from the Code file:
// points vairable
private int points;
// Property for points
public int Points
{
get { return points; }
set { points = value; }
}
protected void Timer_Tick(object sender, EventArgs e)
{
Random random = new Random();
int visible;
foreach (Button button in buttonList)
{
visible = random.Next(1, 10);
if (visible == 3)
button.Visible = true;
else
button.Visible = false;
}
lblPoints.Text = "Score: " + Points + " p";
}
protected void Button1_Click(object sender, EventArgs e)
{
Points = Points + 1;
}
Where is your Points variable declared?
I think it might be a member of the Whack_a_mole WebForm class and that is why it doesn't update. The instance of the WebForm is only used for 1 Postback, and then it is destroyed.
But more important, for a game like this you should use JavaScript or SilverLight.