I get the link in "https://www.youtube.com/watch?v=SIs7ZsMCUWA&t=327s"
I want to change from aspx to winform
the problem:
in aspx
protected void Page_Load(object sender, EventArgs e)
{
if (Session["TokenQueue"] == null)
{
Queue<int> queueTokens = new Queue<int>();
Session["TokenQueue"] = queueTokens;
}
}
protected void btnPrinToken_Click(object sender, EventArgs e)
{
Queue<int> tokenQueue = (Queue<int>)Session["TokenQueue"];
lblStatus.Text = " Terdapat " + tokenQueue.Count.ToString() + " Antrian ";
if (Session["LastTokenNumberIssued"] == null)
{
Session["LastTokenNumberIssued"] = 0;
}
int nextTokenNumberTobeIssued = (int)Session["LastTokenNumberIssued"] + 1;
Session["LastTokenNumberIssued"] = nextTokenNumberTobeIssued;
tokenQueue.Enqueue(nextTokenNumberTobeIssued);
AddTokensToListBox(tokenQueue);
}
in c# can't read session?
Session["TokenQueue"] = queueTokens;
how to use session in c# winform?
Session normally helps us to maintain information for a user across multiple pages in a web application. When you are converting any web application to windows application you need to know the certain aspects of web application. As session is pretty common in most of web application frameworks. You can achieve same behavior by static variables in any language. In C# you can make a class to hold such information in static variables like this
internal static class SESSIONWINFORM
{
public static string TokenQueue = string.Empty;
public static DateTime LastLogin = DateTime.MinValue;
// more variables as you needed
}
Then you assign these variables values at particular events of your windows application for example in login method to save logged in time like this
protected bool login(string username, string password) {
if (succesfullLogic)
{
SESSIONWINFORM.LastLogin = DateTime.Now;
....
}
}
And to show in a Label1 to user his last login in a WinForm. You can set it text like this
Label1.Text = SESSIONWINFORM.LastLogin;
You don't need sessions since Windows apps run within the user context. There is always a single user.
I would advice to make the variable a static variable, since then it really is shared for the lifetime of the session, as it would in ASP.NET. What if you make a Session class in your Winforms project and mimic the session behavior? That would make it easier to exchange code between your projects.
Related
my project
I was wondering how to save the User input in a ListView and prevent it from disappearing when I go to another Form
if (string.IsNullOrEmpty(txtName.Text) || string.IsNullOrEmpty(txtReview.Text))
return;
ListViewItem item = new ListViewItem(txtName.Text);
item.SubItems.Add(txtReview.Text);
listView1.Items.Add(item);
txtName.Clear();
txtReview.Clear();
As far I got your concern! You have a form in which you are adding a reviews. You are closing it soon after adding review. But you want all previous reviews when you visit that form again.
you cannot use database (it certainly would have been easiest way to do though), but you are allowed to use file system (you said text files, i'm assuming serialization too)
But reading and writing files on every now and then is costly process, I would recommend you keep data in memory cache (insert new reviews, update and delete them if there may such option). While closing an application, you store last updated copy into file and while starting software you read that file to get last updated copy of data.
(this way of storing data on closing software can cause data loss when software crash or stopped abnormally. but as it is class project, i would not worry much about that. however you can always use low priority thread to store data periodically)
For this approach, I would recommend to implement MVVM architecture
At least you should create a class which store all the data statically
(why static? it is an interesting question and i m leaving it on you to find out the answer)
Example code For Model:
public class Model
{
public static Dictionary<string, Review> ReviewData;
//this method should be called at application startup.
public static void SetModel()
{
//Desrialize lastly saved file, I'm just initializing it with new
ReviewData = new Dictionary<string, Review>();
}
public static void AddReview(string movie, string reviewerName, string review)
{
if (!ReviewData.ContainsKey(movie + "-" + reviewerName))
{
ReviewData.Add(movie + "-" + reviewerName, new Review(reviewerName, reviewerName));
}
}
}
public class Review
{
public string reviewerName;
public string review;
public Review(string reviewerName, string review)
{
this.reviewerName = reviewerName;
this.review = review;
}
}
Example Code for Add review form:
private void btnPost_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(txtName.Text) || string.IsNullOrEmpty(txtReview.Text))
return;
//First we should set Model data
Model.AddReview("moive1", txtName.Text, txtReview.Text);
LoadListView();
}
private void AddReviewForm_Load(object sender, EventArgs e)
{
LoadListView();
}
private void LoadListView()
{
listView1.Clear();
foreach (string reviewKey in Model.ReviewData.Keys)
{
Review review = Model.ReviewData[reviewKey];
ListViewItem item = new ListViewItem(review.reviewerName);
item.SubItems.Add(review.review);
listView1.Items.Add(item);
}
}
And last thing, while closing entire application, store lastly updated copy of Model.ReviewData (Serialize it).
Im having trouble converting wpf to asp.net using mqtt. My code did not show any error but when i launch and input some text and a button click,it will show me an error
"An exception of type 'System.NullReferenceException' occurred in WebApplication4.dll but was not handled in user code"
public partial class Testing : System.Web.UI.Page
{
MqttClient client;
string clientId;
protected void Page_Load(object sender, EventArgs e)
{
}
public void MainWindow()
{
string BrokerAddress = "test.mosquitto.org";
client = new MqttClient(BrokerAddress);
// register a callback-function (we have to implement, see below) which is called by the library when a message was received
client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;
// use a unique id as client id, each time we start the application
clientId = Guid.NewGuid().ToString();
client.Connect(clientId);
}
void client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
{
string ReceivedMessage = Encoding.UTF8.GetString(e.Message);
txtReceived.Text = ReceivedMessage;
}
protected void btnPublish_Click(object sender, EventArgs e)
{
if (txtTopicPublish.Text != "")
{
// whole topic
string Topic = "" + txtTopicPublish.Text + "";
// publish a message with QoS 2
client.Publish(Topic, Encoding.UTF8.GetBytes(txtPublish.Text), MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE, true);
}
else
{
Page.ClientScript.RegisterStartupScript(this.GetType(), "Scripts", "<script>alert('You have to enter a topic to publish!')</script>");
}
}
It seems to be a lack of understanding of the ASP.NET page lifecycle.
In WPF, the lifecycle spans from when you run the program til when it is closed; it is statefull. ASP.NET is not; whatever you do in a Page_Load (and the other lifecycle events) will be disposed with the completion of rendering the page.
You have a few ways of solving your problem.
You can keep the MqttClient instance in the Application object. This keeps the instance alive from when the AppPool starts (instantiate the client in the Application_Start event in Global.asax. It is fired when the AppPool starts) and until it shuts down (Application_End, where you get the opportunity to shut your MqttClient down gracefully if you want/need to). It is shared between all users and can be accessed anywhere with Application[key] where key is any string, "MqttClient" for example.
You can keep it in the Session object the same way you would in the Application object. You can use Sesson_Start and Session_End in the same way. The Session object is unique to each user, in terms of it staying alive until the user stops browsing your website.
You can instantiate MqttClient every time you need it or with every Page_Load.
I want to know if i can count a specific session variable.
I want to make a count of how many users are currenty logged in to the site and how many users are visiting the site right now.
Here is what i did (code)
public void Session_OnStart()
{
Application.Lock();
Application["UsersOnline"] = (int)Application["UsersOnline"] + 1;
Application.UnLock();
}
public void Session_OnEnd()
{
Application.Lock();
Application["UsersOnline"] = (int)Application["UsersOnline"] - 1;
Application.UnLock();
}
This code works fine, But now I got no idea how to count users that are logged in. I want to do something like that:
public void Session_OnStart()
{
if (Session["IsLoggedIn"] == "true")
{
Application.Lock();
Application["UsersLoggedIn"] = (int)Application["UsersLoggedIn"] + 1;
Application.UnLock();
}
}
and then if the session is closed it will subtract 1 from the Application["UsersLoggedIn"]. My problem is that I cant count the 'IsLoggedIn' session on session start, because it is null and hence it wont work. So now we get to my quistion, Is there anyway to trigger the count of that application variable? Like to create an event when that session is true and then tell the application to add +1 to the counter on that event? Im sorry if my quistion wasnt clear, Please ask me for more deatils if its not clear and you just had no idea what i want from you.
Thank you for your help!
Dirty, hacky, inefficient, solution (assumes use of forms authentication):
public void Global_BeginRequest(object sender, EventArgs e)
{
if(
Context.User != null &&
!String.IsNullOrWhiteSpace(Context.User.Identity.Name) &&
Context.Session != null &&
Context.Session["IAMTRACKED"] == null
)
{
Context.Session["IAMTRACKED"] = new object();
Application.Lock();
Application["UsersLoggedIn"] = Application["UsersLoggedIn"] + 1;
Application.UnLock();
}
}
At a high level, this works by, on every request, checking if the user is logged in and, if so, tags the user as logged in and increments the login. This assumes users cannot log out (if they can, you can add a similar test for users who are logged out and tracked).
This is a horrible way to solve your problem, but it's a working proto-type which demonstrates that your problem is solvable.
Note that this understates logins substantially after an application recycle; logins are much longer term than sessions.
I think the session items are client sided.
You can create a query to count the open connections (hence you're working with a MySQL database.)
Another option is to use external software (I use the tawk.to helpchat, which shows the amount of users visiting a page in realtime).
You could maybe use that, making the supportchat invisible, and only putting it on paging which are accesible for loggedin users.
OR
Execute an update query which adds/substracts from a column in your database (using the onStart and OnEnd hooks).
That is the problem that you cannot do it using Session[] variables. You need to be using a database (or a central data source to store the total number of active users). For example, you can see in your application, when the application starts there is no Application["UsersOnline"] variable, you create it at the very instance. That is why, each time the application is started, the variable is initialized with a new value; always 1.
You can create a separate table for your application, and inside it you can then create a column to contain OnlineUsers value. Which can be then incremented each time the app start event is triggered.
public void Session_OnStart()
{
Application.Lock();
Application["UsersOnline"] = (int)Application["UsersOnline"] + 1;
// At this position, execute an SQL command to update the value
Application.UnLock();
}
Otherwise, for every user the session variable would have a new value, and you would not be able to accomplish this. Session variables were never designed for such purpose, you can access the variables, but you cannot rely on them for such a task. You can get more guidance about SQL commands in .NET framework, from MSDN's SqlClient namespace library.
Perhaps I am missing something, but why not something like this:
public void Session_OnStart()
{
Application.Lock();
if (Application["UsersOnline"] == null )
{
Application["UsersOnline"] = 0
}
Application["UsersOnline"] = (int)Application["UsersOnline"] + 1;
Application.UnLock();
}
Maybe I'm missing something, but is there a reason you don't just want to use something like Google Analytics?
Unless you're looking for more queryable data, in which case I'd suggest what others have; store the login count to a data store. Just keep in mind you also have to have something to decrement that counter when the user either logs out or their session times out.
Try this. It may help you.
void Application_Start(object sender, EventArgs e)
{
Application["cnt"] = 0;
Application["onlineusers"] = 0;
// Code that runs on application startup
}
void Session_Start(object sender, EventArgs e)
{
Application.Lock();
Application["cnt"] = (int)Application["cnt"] + 1;
if(Session["username"] != null)
{
Application["onlineusers"] = (int)Application["onlineusers"] + 1;
}
else
{
Application["onlineusers"] = (int)Application["onlineusers"] - 1;
}
Application.UnLock();
// Code that runs when a new session is started
}
now you can display the number of users(Without Loggedin):
<%=Application["cnt"].ToString()%>
and number of online users:
<%=Application["onlineusers"].ToString()%>
Let's say I have a thread that waits for a user to click a button before advancing:
System.Threading.AutoResetEvent dialoguePause = new System.Threading.AutoResetEvent(false);
public void AskQuestion()
{
/* buttons containing choices created here */
dialoguePause.WaitOne();
/*Code that handles choice here */
}
public void Choice_Clicked(object sender, EventArgs e)
{
dialoguePause.Set();
}
How can I pass data from the thread Choice_Clicked is on to AskQuestion without relying on class variables? The best I can do is this:
System.Threading.AutoResetEvent dialoguePause = new System.Threading.AutoResetEvent(false);
string mostRecentChoice;
public void AskQuestion()
{
/* buttons containing choices created here */
dialoguePause.WaitOne();
MessageBox.Show("You chose " + mostRecentChoice + ".");
}
public void Choice_Clicked(object sender, EventArgs e)
{
mostRecentChoice = (sender as Button).Content.ToString(); //Ugly!
dialoguePause.Set();
}
There are many ways to achieve this:
Use a property in a Singleton or Monostate. There is always one instance of such property, so regardless which thread writes, and which reads, the will share it, as long as they are in one Application Domain.
Use messaging
If you are in same class, use field or property (look out for cross-threads!)
...
What I am trying to say, it depends on the application. I have no clue if this is WinForm, WPF or Web ...
I'm currently developing a metro app in which the user can change current language at runtime and all the custom controls that are loaded must update their text regarding to the new language. Problem is that when I change the language using the following code, the app language changes but it will only update text when I restart my app because the pages and controls that are already rendered are cached.
LocalizationManager.UICulture = new System.Globalization.CultureInfo((string)((ComboBoxItem)e.AddedItems[0]).Tag);
Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = ((ComboBoxItem)e.AddedItems[0]).Tag as String;
What should I do to force updating text of all custom controls at runtime without restarting my app?
Use this:
var NewLanguage = (string)((ComboBoxItem)e.AddedItems[0]).Tag;
Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = NewLanguage;
Windows.ApplicationModel.Resources.Core.ResourceContext.GetForViewIndependentUse().Reset();
//Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView().Reset();
Windows.ApplicationModel.Resources.Core.ResourceManager.Current.DefaultContext.Reset();
and then reload your Page, using Navigate method:
if (Frame != null)
Frame.Navigate(typeof(MyPage));
In order to respond right away, you would need to reset the context of the resource manager.
For Windows 8.1:
var resourceContext = Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView();
resourceContext.Reset();
You will still need to force your page to redraw itself and thus re-request the resources to get the changes to take place. For Windows 8, you can see https://timheuer.com/blog/archive/2013/03/26/howto-refresh-languages-winrt-xaml-windows-store.aspx
You can change the app's language at runtime with the help of this source code. I took help from this and manipulated my app's language settings page as follows:
In languageSettings.xaml.cs:
public partial class LanguageSettings : PhoneApplicationPage
{
public LanguageSettings()
{
InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (ChangeLanguageCombo.Items.Count == 0)
{ ChangeLanguageCombo.Items.Add(LocalizationManager.SupportedLanguages.En);
ChangeLanguageCombo.Items.Add(LocalizationManager.SupportedLanguages.Bn);
}
SelectChoice();
}
private void ButtonSaveLang_OnClick(object sender, RoutedEventArgs e)
{
//Store the Messagebox result in result variable
MessageBoxResult result = MessageBox.Show("App language will be changed. Do you want to continue?", "Apply Changes", MessageBoxButton.OKCancel);
//check if user clicked on ok
if (result == MessageBoxResult.OK)
{
var languageComboBox = ChangeLanguageCombo.SelectedItem;
LocalizationManager.ChangeAppLanguage(languageComboBox.ToString());
//Application.Current.Terminate(); I am commenting out because I don't neede to restart my app anymore.
}
else
{
SelectChoice();
}
}
private void SelectChoice()
{
//Select the saved language
string lang = LocalizationManager.GetCurrentAppLang();
if(lang == "bn-BD")
ChangeLanguageCombo.SelectedItem = ChangeLanguageCombo.Items[1];
else
{
ChangeLanguageCombo.SelectedItem = ChangeLanguageCombo.Items[0];
}
}
}
***Note: Before understanding what I did on LanguageSettings page's code behind, you must implement the codes from the link as stated earlier. And also it may be noted that I am working on windows phone 8