ASP.Net - Unable to change text of Label from a Delegate Event - c#

Hi I'm trying to make a single .html page that displays out the readings of my Raspberry Pi in Real-Time.
The Data is being sent over which triggers the Delegate.
However, the function that the Delegate triggers isn't able to interact with any Control in my ASP.Net Page.
Here's how my code looks like:
public partial class newIndex : System.Web.UI.Page
{
DataComms dataComms;
public void commsDataReceive(string strData)
{
// This line is able to successfully print out the strData
System.Diagnostics.Debug.WriteLine(strData);
// This line doesn't throw an error but doesn't work
Label1.Text = strData;
}
private void InitComms()
{
dataComms = new DataComms();
dataComms.dataReceiveEvent += new DataComms.DataReceivedDelegate(commsDataReceive);
}
protected void Page_Load(object sender, EventArgs e)
{
InitComms();
}
}
My theory is that after the Page loads I'm unable to make any changes to it dynamically?? So I can solve this using an UpdatePanel Right?
Well I tried that too and it didn't work also as I had to call UpdatePanel1.Update() which is accessing the control UpdatePanel.
If anyone could help I'll be so thankful!

Server pages do not work in this way. Most likely page is already sent to browser by the time commsDataReceive is fired. I guess you have only one "client" to show this information so you can make dataComms as static and update code to follow. This is certainly not the best solution but should work for your requirement
public partial class newIndex : System.Web.UI.Page
{
static DataComms dataComms;
static string lastData="";
public void commsDataReceive(string strData)
{
// This line is able to successfully print out the strData
System.Diagnostics.Debug.WriteLine(strData);
// This line doesn't throw an error but doesn't work
lastData = strData;
}
protected void Page_Load(object sender, EventArgs e)
{
if (dataComms != null)
{
dataComms = new DataComms();
dataComms.dataReceiveEvent += new DataComms.DataReceivedDelegate(commsDataReceive);
}
Label1.Text = lastData;
}
}

Related

Why am I getting a NullReferenceException when subscribing to event in Xamarin.Forms, but only on iOS?

I have a page - Page A, that has a method that subscribes to an event on another page - Page B. I figured I could instantiate Page B in my code in Page A before having my method in Page A subscribe to the event in Page B, and then finally pushing Page B to the navigation stack.
Unfortunately, I keep getting a NullReferenceException on the line in which the method subscribes to the event when I test my application on iOS. The code runs perfectly fine when I deploy and test as an Android application, but I always get the NullReferenceException on iOS. What's causing this exception to be thrown, and how can I fix it? Why is it platform specific to iOS?
Code on Page A
var confirmationPage = new EmailConfirmationPage(username);
confirmationPage.EmailConfirmed += this.OnEmailConfirmed;
await this.Navigation.PushModalAsync(confirmationPage);
...
private void OnEmailConfirmed(object source, EventArgs args)
{
this.LabelMessage.Text = "Email Confirmed!";
}
Code on Page B
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace appFBLA2019
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class EmailConfirmationPage : ContentPage
{
private string username;
private string email;
public delegate void EmailConfirmedEventHandler(object source, EventArgs args);
public event EmailConfirmedEventHandler EmailConfirmed;
public EmailConfirmationPage(string username)
{
InitializeComponent();
this.username = username;
this.LabelTitle.Text = "Loading...";
GetEmail();
}
private void GetEmail()
{
try
{
ServerConnector.QueryDB($"getEmail/{this.username}/-");
this.email = ServerConnector.ReceiveFromDB();
this.LabelTitle.Text = $"Enter the confirmation code sent to {this.email.Split('/')[1]}";
}
catch
{
this.LabelMessage.Text = "Connection Error: Please Try Again.";
}
}
private async void ButtonConfirmEmail_Clicked(object sender, EventArgs e)
{
try
{
string userInputToken = this.EntryConfirmationCode.Text.Trim();
ServerConnector.QueryDB($"confirmEmail/{this.username}/{userInputToken}/-");
string returnData = ServerConnector.ReceiveFromDB();
if (returnData == "true/-")
{
OnEmailConfirmed();
await this.Navigation.PopModalAsync(true);
}
else
{
this.LabelMessage.Text = "Email could not be confirmed. Please try your code again.";
}
}
catch
{
this.LabelMessage.Text = "Connection Error: Please try again.";
}
}
private void ButtonFixEmail_Clicked(object sender, EventArgs e)
{
string newEmail = this.EntryChangeEmail.Text;
ServerConnector.QueryDB($"changeEmail/{this.username}/{newEmail}/-");
string result = ServerConnector.ReceiveFromDB();
if (result == "true/-")
{
this.LabelMessage.Text = $"Enter the confirmation code sent to {newEmail}";
}
else
{
this.LabelMessage.Text = $"Email could not be changed: {result.Split('/')[1]}";
}
}
private async void ButtonClose_Clicked(object sender, EventArgs e)
{
await this.Navigation.PopModalAsync(true);
}
protected virtual void OnEmailConfirmed()
{
EmailConfirmed?.Invoke(this, EventArgs.Empty);
}
}
}
Call Stack before subscribing method to event:
0xC0 in appFBLA2019.CreateAccountPage.ButtonCreateAccount_Clicked at C:\Users\chung\source\repos\appFBLA2019\appFBLA2019\appFBLA2019\CreateAccountPage.xaml.cs:30,21 C#
Call stack after subscribing method to event:
0x1B8 in appFBLA2019.CreateAccountPage.ButtonCreateAccount_Clicked at C:\Users\chung\source\repos\appFBLA2019\appFBLA2019\appFBLA2019\CreateAccountPage.xaml.cs:39,13 C#
Upon further testing, I noticed that this issue occurs on both iOS and Android, but ONLY when running the application with Xamarin Live Player. I contacted Microsoft and they pointed out that Xamarin Live Player unfortunately has limitations. Deploying directly to a device causes no issues, and the code runs fine.

Windows 8 App - Pass Data to MainPage

I want to pass data from a child page of the MainPage in my app. The problem, from what I can tell is that there is a splash loading screen that navigates to the MainPage and I want to write an "If navigated from child page" block to include in the OnNavigatedTo.
Here is my MainPage.xaml.cs code:
protected override void OnNavigatedTo(NavigationEventArgs args)
{
if (base.OnNavigatedFrom(args) = ChildPage)
{
// Code for: If navigated from child page
ReturnData returnData = args.Parameter as ReturnData;
this.myNewString = returnData.myString;
}
base.OnNavigatedTo(args);
}
I found out that you cannot return data the way it is used by passing data to another page for Windows 8 Apps. You cannot return data they way you pass it i.e. this.Frame.Navigate(typeof(MainPage), passData); For the solution, I created a 'Completed' event and and called it from the MainPage C# code behind.
MainPage.xaml.cs:
protected override void OnNavigatedFrom(NavigationEventArgs args)
{
if (args.SourcePageType.Equals(typeof(ChildPage)))
(args.Content as ChildPage).Completed += OnChildPageCompleted;
base.OnNavigatedFrom(args);
}
void OnChildPageCompleted(object sender, ReturnData args)
{
// Code to run if returned back to MainPage from ChildPage
this.myNewString = returnData.myString;
(sender as ChildPage).Completed -= OnChildPageCompleted;
}
ReturnData.cs:
namespace MyTestApp
{
class ReturnData
{
public String myString { set; get; }
}
}
ChildPage.xaml.cs:
public event EventHandler<ReturnData> Completed;
ChildPage.xaml.cs:
protected override void OnNavigatedFrom(NavigationEventArgs args)
{
if (Completed != null)
{
// Create ReturnData object
ReturnData returnData = new ReturnData();
returnData.myString = newStringChanged;
// Fire Completed event
Completed(this, returnData);
}
base.OnNavigatedFrom(args);
}

passing value from another class to textbox in form?

I have a class and a form. the class is intended to do some processes when event is raised and return back the values to the form to display only. I kind of have problem passing values back to form. For instance, I have this code in class print:
public class PrintClass : Form1
{
public void printEventHandler(object sender, EventArgs e)
{
string text = "Process Completed";
append_Tbox(text);
}
}
and the method in form1 to display the text:
public void append_Tbox(string s)
{
TboxPrint.AppendText(s);
}
However, nothing is displayed. I believe there is something wrong, but I can't figure it out.
What is the fastest way to pass values from the class to form?
First off, your processing class shouldn't extend Form1. This is giving you the illusion that you can access the methods of your existing form, but it's not doing what you think it is. You're creating an entirely new form when you do this, and just not showing it. That form has it's own set of all instance fields, so you're not accessing the controls of your main form. Even if this would work (and it won't) it's not a well designed solution.
The proper way to do this is actually much easier. You just need to have your other class return a value from it's method:
public class PrintClass
{
public string DoWork()
{
Thread.Sleep(2000);//placeholder for real work.
return "Process Completed";
}
}
Now your main form can just call that method and append the return value to a textbox.
Once you do this you'll have an entirely separate issue. If you do the work in the UI thread you'll be blocking that UI thread while the work takes place, preventing the form from being repainted, or any other events from being handled. You need to do the work in a background thread and then marshal back to the UI thread to update the UI with the results. There are a number of ways of doing this, but if you have C# 5.0 using await is by far the easiest:
public class Form1 : Form
{
private void SomeEventHandler(object sender, EventArgs args)
{
string result = await Task.Run(()=>new PrintClass().DoWork());
TboxPrint.AppendText(result);
}
}
If you need a C# 4.0 solution you can use ContinueWith, which is more or less what the above will be translated to, but it's not quite as clean of syntax.
public class Form1 : Form
{
private void SomeEventHandler(object sender, EventArgs args)
{
Task.Factory.StartNew(()=>new PrintClass().DoWork())
.ContinueWith(t => TboxPrint.AppendText(t.Result)
, CancellationToken.None
, TaskContinuationOptions.None
, TaskScheduler.FromCurrentSynchronizationContext());
}
}
I have create delegate in Main Form
public delegate void LoginDelegate(string s);
public partial class AirLineReservationMDI : Form
{
LoginDelegate loginAirLineDelegate;
}
loginAirLineDelegate = new LoginDelegate(DisableToolStripMenuItems);
public void DisableToolStripMenuItems(string s)
{
this.viewToolStripMenuItem.Visible = true;
this.bookingToolStripMenuItem.Visible = true;
this.existingUserToolStripMenuItem.Visible = false;
this.newUserToolStripMenuItem.Visible = false;
this.toolStripStatusUserID.Text = "USerID :- "+s;
this.LoginUserId = s;
}
in Another Class, (I have passed delagete object to this class )
I fired the Delegate
logDelegate(textBoxUserName.Text);
I used Action<T> delegate to solve the problem. here is the code and it works fine.
class PrintClass
{
public Action<string> DisplayDelegate;
public void printEventHandler(object sender, EventArgs e)
{
string text = "Event Handled, and text value is passed";
var copy = DisplayDelegate;
if (copy != null)
{
copy(text);
}
}
}
and in `Form1.cs' :
private void Form1_Load(object sender, EventArgs e)
{
PrintClass p = new PrintClass();
BtnPrint.Click += p.printEventHandler;
//subscrite the displayevent method to action delegate
p.DisplayDelegate += DisplayEvent;
}
public void DisplayEvent(string s)
{
Invoke(new Action(() => TboxPrint.AppendText(s)));
}
so the text 'Event Handled, and text value is passed' is displayed on the textbox.
I m not sure if it is the efficient way.
Thanks guys.

ASP.NET call button action from different class

I have a class Lot with a function AddPiece(piece).
I also have a Page with a button btnPanel that on click fires the function
public void btnPanel_OnClick(object sender, EventArgs e){}
I want to call the btnPanel_OnClick from the Addpiece function but when I try to do it it does not show in the intlliSense and I get this compilation error "The name 'btnPanel_OnClick' does not exist in the current context". Both classes are in the same namespace. Is this possible?
Here is what I have:
namespace GraphicW_Array
{
public partial class Board : System.Web.UI.Page
{
public void btnPanel_OnClick(object sender, EventArgs e)
{
...code...
}
}
}
and
namespace GraphicW_Array
{
public class Lot
{
public void addPiece(int piece)
{
lotPresent[lotLoad] = piece;
lotLoad++;
}
}
}
I think the answer is yes you can but you probably don't want to. To call the method you need and instance of your page class so you could do
namespace GraphicW_Array
{
public class Lot
{
public void addPiece(int piece)
{
lotPresent[lotLoad] = piece;
lotLoad++;
var myPage = new Board();
myPage.btnPanel_OnClick(null,EventArgs.Empty);
}
}
}
But what would that actually do? I have no idea because you haven't posted the code but i suspect it won't do anything useful for you.
What are you actually trying to achieve?
Maybe this is want you want
namespace GraphicW_Array
{
public class Lot
{
public void addPiece(int piece, Board myPAge)
{
lotPresent[lotLoad] = piece;
lotLoad++;
myPage.btnPanel_OnClick(null,EventArgs.Empty);
}
}
}
Then in your page you can call it like this:
var myLot = new Lot();
myLot.addPiece(4,this);
Yes, this is possible.
Ensure your Lot class has a reference to the Board class in order to be able to call it, or define an event on it that the Board class can subscribe to and that will call this mathod when the event fires.
If you don't use the sender and e parameters, just pass a null and EventArgs.Empty.
You can call page's event by passing either null(if sender and EventArgs is not mandatory) but below is the better way to go.
It is not wise and not good practice to call a event from a class, however you can create another method with arguments in your class and then call it with desired parameters when it is needed.
This is can be accomplished as below:
Say you have below event
public void btnPanel_OnClick(object sender, EventArgs e)
{
//Do some common tasks to do here
}
Rearrange it as below:
public void btnPanel_OnClick(object sender, EventArgs e)
{
Lot lot = new Lot();
lot.CommonFunction(arg1, arg2); // Pass required data
}
public class Lot
{
public void AFunction()
{
//Do something
//...
CommonFunction(arg1, arg2); // Pass required data
//...
//Do something
}
public void CommonFunction(string arg1, string arg2)
{
// Do some common tasks to do here
}
}

Selfmade MessageBox.Show() in ASP.NET

I want to rebuild the "look & feel" of MessageBox.Show() of WinForms applications.
With "look & feel" I mean to JUST CALL the MessageBox.Show() command with the logic of my already implemented ShowMessage method.
My current codebehind:
public partial class Testpage : System.Web.UI.Page
{
public enum MessageBoxIcon { Information, Error, Warning }
protected void Page_Load(object sender, EventArgs e)
{
ShowMessage("Testmessage", MessageBoxIcon.Error, ex);
}
private void ShowMessage(string title, string message, MessageBoxIcon type, Exception ex)
{
if (type == MessageBoxIcon.Information)
{
pnlMsgBox.CssClass = "MessageBoxInformation";
imgMsgBox.ImageUrl = "Resources/img/icon/MessageBoxIcon.Information.png";
}
else if (type == MessageBoxIcon.Warning)
{
pnlMsgBox.CssClass = "MessageBoxWarning";
imgMsgBox.ImageUrl = "Resources/img/icon/MessageBoxIcon.Warning.png";
}
else if (type == MessageBoxIcon.Error)
{
pnlMsgBox.CssClass = "MessageBoxError";
imgMsgBox.ImageUrl = "Resources/img/icon/MessageBoxIcon.Error.png";
}
else
throw new NotImplementedException();
lblMsgBox.Text = "<span style=\"font-size: large;\">" + title + "</span><br /><br />" + message;
#if (DEBUG)
if (ex != null)
lblMsgBox.Text += "<br /><br /><b>Debug information:</b> " + ex.Message;
#endif
pnlMsgBox.Visible = true;
updPnl.Update();
}
}
I'd like to call something like this:
protected void Page_Load(object sender, EventArgs e)
{
MessageBox.Show("Testmessage", MessageBoxIcon.Error, ex);
}
But
public static class MessageBox : Testpage
{
public static void Show(string message)
{
// do stuff with the page controls.
}
}
doesn't work as you all know, because Testpage isn't static.
Does anybody have some suggestions for me?
Reading the comments to the previous answer, I think next:
Its difficult to get access to current page context from the separated static class. So then, i recomendate do next:
Define next interface:
public interface IMessageBoxContainer
{
UpdatePanel UpdatePanel { get; }
Label Label { get; }
}
and implement him by your page as:
public partial class _Default : System.Web.UI.Page, IMessageBoxContainer
{
protected void Page_Load(object sender, EventArgs e)
{
}
public UpdatePanel UpdatePanel
{
get { return updatePanel1; }
}
public Label Label
{
get { return label1; }
}
}
This steps provide you to get access to your page from anywhere. After that implement you MessageBox NON-static class:
public class MessageBox
{
private IMessageBoxContainer container = null;
public MessageBox(IMessageBoxContainer _container)
{
container = _container;
}
public void Show(string message)
{
container.Label.Text = message;
container.UpdatePanel.Update();
}
}
Why non-static? Becouse if you do container field as static and set him value anywhere in page (for example in Page_Load), when another page will load - your container property will reset. But without this field, that pointer to your current page, you cant get access to your specefied controls.
After that you can use your class like that:
protected void Button1_Click(object sender, EventArgs e)
{
var box = new MessageBox(this);
box.ShowMessage("hello world");
}
So, you get separated implementation logic of your MessageBox and simple using him, yes? But unfurtunently, its non-static.
Try like this:
public static class MessageBox
{
public static void Show(string message)
{
HttpContext.Current.Response.Write(string.Format("<script>alert('{0}');</script>", message));
}
}
Of course, you will need to implement your own correct JavaScript to display you MessageBox on client-side. But I thing – you approach is wrong. For you method programming try to look in ASP.NET MVC, becouse classic ASP.NET do not fully support JavaScript coding.

Categories

Resources