Is using OnPropertyChanged(string.Empty); a practice to avoid? - xamarin.forms

We have OnPropertyChanged(string.Empty); in quite a few places in our Xamarin.Forms application. In general I feel like we shouldn't be saying "Hey, notify everyone that all the properties on this object have changed."
An example of where we do this is in some data syncing event handlers in a view model that inherits
private void OnSyncEnding(object sender, EventArgs e){
SyncItem = syncService.Value.SyncState;
OnPropertyChanged(string.Empty);
}
private void OnSyncStarting(object sender, EventArgs e){
SyncItem = syncService.Value.SyncState;
OnPropertyChanged(string.Empty);
}
private void OnSyncFormSuccessful(object sender, EventArgs e){
SyncItem = syncService.Value.SyncState;
OnPropertyChanged(string.Empty);
}
My question is: How much work does this actually trigger and when is using OnPropertyChanged(string.Empty); the correct thing to do instead of calling OnPropertyChanged("SomeProperty") for all the properties required?

Related

Pass value from one xaml page to another xaml page in silverlight

Hello I am very new to Silverlight and I want to pass value from one Xaml page to another Xaml page in Silverlight. I got some solution for that as
protected void btn_click(object sender, RoutedEventArgs e)
{
NavigationService.Navigate(new Uri("/Page1.xaml?key1"=txtname.Text, UriKind.Relative));
}
but I am finding an error in it as
An object reference is required for the non-static field, method, property System.Windows.Navigation.NavigationService.Navigate(System.Uri)'
Syntax issue. unless that is a typo
protected void btn_click(object sender, RoutedEventArgs e)
{
NavigationService.Navigate(new Uri("/Page1.xaml?key1"=txtname.Text, UriKind.Relative));
}
should change to...
protected void btn_click(object sender, RoutedEventArgs e)
{
NavigationService.Navigate(new Uri("/Page1.xaml?key1="+txtname.Text, UriKind.Relative));
}
Note the change from
"/Page1.xaml?key1"=txtname.Text
to
"/Page1.xaml?key1="+txtname.Text

ASP.NET initialization of array

I have website with array (list) of 1000 objects, these objects are loading from json to array every website refresh. I would like to load these objects from json to array only once and keep it in RAM for others users. Because everytime read file is much slower than read it from RAM.
I am using ASP.NET Web Forms
How is it posssible?
I would recommend to define the array as an static member of a class and then initialize it with help of Global.asax, use the Application_Start event handler.
to add Global.asax to you project in Visual Studio:
File -> New -> File -> Global Application Class
Here is a sample C# code for Global.asax.cs:
public class Global : HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
// ... Your initialization of the array done here ...
}
protected void Session_Start(object sender, EventArgs e)
{
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
}
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
}
protected void Application_Error(object sender, EventArgs e)
{
}
protected void Session_End(object sender, EventArgs e)
{
}
protected void Application_End(object sender, EventArgs e)
{
}
}
Are these values static, i.e., do they stay constant while your application is running? In that case, the easiest way is to cache those values.
You can use static variables for that, but the recommended way is to use the thread-safe Cache object provided by ASP.NET. It can be accessed with the Cache property of the Page or of the HttpContext.
Example:
var myList = (MyListType)Cache["MyList"];
if (myList == null)
{
myList = ...; // Load the list
Cache["MyList"] = myList; // Store it, so we don't need to load it again next time.
}
Further reading:
Caching Application Data

How to save a dictionary value in a viewstate?

I have a questions and answers page when some questions gets hidden and some gets visible depending upon the predecessor answers. at the end i need all the answers.
I am trying to use dictionary for this. I add answers with a key on a changed event of each control. but none of the answers are saved when i move to next section as i am hiding the previous sections.
I am trying to save it in a viewstate and add the values so that my values persists in the dictionary..
Any ideas?
Here is the code:
Dictionary<String, String> Answers;
protected void Page_Load(object sender, EventArgs e)
{
Answers = (Dictionary<String, String>)ViewState["Answers"];
ViewState["Answers"] = Answers;
}
protected void rdb_study_popul_SelectedIndexChanged(object sender, EventArgs e)
{
ViewState["StudySamplepopulation"] = rdb_study_popul.SelectedValue.ToString();
Answers.Add("StudyPopulation", ViewState["StudySamplepopulation"].ToString());
}
Right now, Answers will be empty if I move to next section.
Any help would be greatly appreciated.
i am getting null reference error Object reference not set to an instance of an object.
Public partial class
{
Dictionary Answers;
protected void Page_Load(object sender, EventArgs e)
{
Answers = ( Dictionary<String, String>)ViewState["Answers"];
}
protected void rdb_studysubj_SelectedIndexChanged(object sender, EventArgs e)
{
ViewState["StudySubjectAnimal"] = rdb_studysubj.SelectedValue.ToString();
studysub_popul.Visible = true;
Answers.Add("StudySubjectAnimal", ViewState["StudySubjectAnimal"].ToString());
ViewState["Answers"] = Answers;
}
You do not need to update the ViewState in page load, because it has not changed yet, so remove the assignment of ViewState in your Page_Load and do this instead:
protected void Page_Load(object sender, EventArgs e)
{
// Only read the value from ViewState, do not update it here
Answers = (Dictionary<String, String>)ViewState["Answers"];
}
Now in you event handler, when you are done adding to the Answers, then you should update your ViewState value, like this:
protected void rdb_study_popul_SelectedIndexChanged(object sender, EventArgs e)
{
ViewState["StudySamplepopulation"] = rdb_study_popul.SelectedValue.ToString();
Answers.Add("StudyPopulation", ViewState["StudySamplepopulation"].ToString());
// Now that you are done altering the Answers, save the updated value to ViewState
ViewState["Answers"] = Answers;
}
UPDATE:
You need to check if ViewState is null or not, like this:
Dictionary<String, String> Answers = new Dictionary<String, String>();
protected void Page_Load(object sender, EventArgs e)
{
// Is there anything in ViewState?
if (ViewState["Answers"] != null)
{
// Yes, but only read the value from ViewState, do not update it here
Answers = (Dictionary<String, String>)ViewState["Answers"];
}
}
Note: I changed the declaration of the Answers dictionary to also include instantiating it, so that it will not be null.

WCF\ASP.NET interoperability

I have a server application written in WCF using asynchronous callbacks, and a webforms application in ASP.NET.
All of the communication is fine between the 2 applications, I can call the exposed functions in the server via the web application, and the server can send callbacks to the web application, however sometimes the functions within the callback work, and other times, they don't.
For example, I would like a login button on the web app to send a username and password to the server, the server checks this against the database, and if the login information is correct, it should send a callback, which opens a new page in the web app.
Here is the relevant server code:
public void Login(String username, String password)
{
//DoCheckAgainstDatabase(username, password);
ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>();
callback.LoginSuccess();
}
and the web application code:
private InstanceContext _instanceContext;
private ServiceClient _service;
public CallbackHandler MyCallbackHandler = new CallbackHandler();
protected void Page_Load(object sender, EventArgs e)
{
_instanceContext = new InstanceContext(MyCallbackHandler);
_backEnd = new ServiceClient(_instanceContext, "NetTcpBinding_IAU", "net.tcp://localhost/MyService/Service");
_backEnd.Open();
MyCallbackHandler.LoginSucceeded += OnLoginSucceeded;
}
protected void LoginButton_Click(object sender, EventArgs e)
{
_backEnd.Login(UsernameTextBox.Text, PasswordTextBox.Text);
}
private void OnLoginSucceeded(object sender, EventArgs e)
{
ScriptManager.RegisterStartupScript(this.Page, Page.GetType(), "OpenClientWindow", "window.open('Client.aspx','_self');", true);
}
I can put in breakpoints, and see that everything is working fine, it's just that the code 'ScriptManager.RegisterStartupScript...' does not execute properly all the time.
Could this be something to do with threading? Could anyone suggest a way to fix this please?
Thanks in advance!
David
It occurs to me that it's possible your page life cycle may be ending - or at least getting to the Render stage, which is where the start up script would be written to the output - before the callback is called.
Is it possible to call your service synchronously, and not proceed out of LoginButton_Click until the service call returns?
I think you are missing script tag - wrap your window.oppen with it, like
ScriptManager.RegisterStartupScript(this.Page, Page.GetType(), "OpenClientWindow", "<script>window.open('Client.aspx','_self');</script>", true);
Thank you Ann L. for guidance on this. I have added a ManualResetEvent, and then in the button click method, I wait until I have received the callback, then proceed with opening the new page:
private InstanceContext _instanceContext;
private ServiceClient _service;
public CallbackHandler MyCallbackHandler = new CallbackHandler();
private ManualResetEvent _resetEvent = new ManualResetEvent(false);
protected void Page_Load(object sender, EventArgs e)
{
_instanceContext = new InstanceContext(MyCallbackHandler);
_backEnd = new ServiceClient(_instanceContext, "NetTcpBinding_IAU", "net.tcp://localhost/MyService/Service");
_backEnd.Open();
MyCallbackHandler.LoginSucceeded += OnLoginSucceeded;
}
protected void LoginButton_Click(object sender, EventArgs e)
{
_backEnd.Login(UsernameTextBox.Text, PasswordTextBox.Text);
_resetEvent.WaitOne();
ScriptManager.RegisterStartupScript(this.Page, Page.GetType(), "OpenClientWindow", "window.open('Client.aspx','_self');", true);
}
private void OnLoginSucceeded(object sender, EventArgs e)
{
_resetEvent.Set();
}

How does Global.asax PostAuthenticateRequest event binding happen?

How can I use the PostAuthenticateRequest event of Global.asax? I'm following this tutorial and it mentions that I have to use the PostAuthenticateRequest event. When I added the Global.asax event it created two files, the markup and the code-behind file. Here is the content of the code-behind file
using System;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
namespace authentication
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
}
protected void Session_Start(object sender, EventArgs e)
{
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
}
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
}
protected void Application_Error(object sender, EventArgs e)
{
}
protected void Session_End(object sender, EventArgs e)
{
}
protected void Application_End(object sender, EventArgs e)
{
}
}
}
Now when I type the
protected void Application_OnPostAuthenticateRequest(object sender, EventArgs e)
It is successfully called. Now I want to know how is the PostAuthenticateRequest bound to this Application_OnPostAuthenticateRequest method? How can I change the method to some other?
Magic..., a mechanism called Auto Event Wireup, the same reason you can write
Page_Load(object sender, EventArgs e)
{
}
in your code-behind and the method will automatically be called when the page loads.
MSDN description for System.Web.Configuration.PagesSection.AutoEventWireup property:
Gets or sets a value indicating whether events for ASP.NET pages are automatically connected to event-handling functions.
When AutoEventWireup is true, handlers are automatically bound to events at run time based on their name and signature. For each event, ASP.NET searches for a method that is named according to the pattern Page_eventname(), such as Page_Load() or Page_Init(). ASP.NET first looks for an overload that has the typical event-handler signature (that is, it specifies Object and EventArgs parameters). If an event handler with this signature is not found, ASP.NET looks for an overload that has no parameters. More details in this answer.
If you wanted to do it explicitly you would write the following instead
public override void Init()
{
this.PostAuthenticateRequest +=
new EventHandler(MyOnPostAuthenticateRequestHandler);
base.Init();
}
private void MyOnPostAuthenticateRequestHandler(object sender, EventArgs e)
{
}

Resources