How to pass data from Window to MainWindow in WPF? - c#

Im newbie to programming and now i have a problem with my new login window.
I created a new window for login to my server database,but in my mainwindow how do i call it? I don't know how to draw it up better.
In my login window:
using MyS_Database;
MyServer_Database server;
public void LoginButton_Click(object sender, RoutedEventArgs e)
{
server = new MyServer_Database("ClientName","ServerIP","","",UserID.Text,UserPassword.Password.ToString(),"01",MyServer_Database.LoginType.User,out serverresult)
swith(serverresult)
{
case 0:
Mainwindow.Show();
this.Close();
break;
default:
Environment.Exit(0);
}
}
But when I call a method on my MainWindow which is communicating with the server i have to call it like:
server.GetDataFromUserList();
But It doesn't recognize server,I tried something like Win1.server or similars but I failed.
How could i pass it? Thank you in advance!

The quick answer is to make server public like this:
public MyServer_Database Server { get; set; }
Then you can call it in MainWindow with:
Win1.Server.GetDataFromUserList();
But this is not a good approach. Better approach is to abstract away these kind of operations in different classes via MVVM. Read more about MVVM and you'll find great approaches.
Edit
You should also do one one of these two things:
Don't close Win1 instead do this.Hide();
Keep the instance of MyServer_Database in MainWindow by passing it to the constructor of Win1.
You should put this in MainWindow
public MyServer_Database Server { get; set; }
and When needed call this:
var Win1 = new LoginWindow(Server);
Then you have access to Server object in MainWindow

Related

Prism WPF Closing view and dispose autowired ViewModel

In short the behaviour i want to accomplish is LOGIN->LOGOUT->LOGIN
My application starts with a login view. After authentication, it close and the MainView open:
public void Authenticated(){
MainWindow main = new MainWindow();
main.Show();
if (Application.Current.Windows.Count > 1) {
Application.Current.Windows[0].Close();
}
this.CloseAction();
}
the CloseAction is just an action variable which close from the codebehind like so
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
if ( (this.DataContext as MainWindowViewModel)!.CloseAction == null )
(this.DataContext as MainWindowViewModel)!.CloseAction = new Action(this.CloseH);
}
private void CloseH() {
this.Close();
}
}
My main cointains also two view regions pushed from the logic of the MainViewViewModel (THOSE TWO ARE USERCONTROLS)
_regionManager.RegisterViewWithRegion("FileTreeRegion", typeof(FileTree));
_regionManager.RegisterViewWithRegion("FileDetailsRegion", typeof(FileDetails));
At some point if i need to logout i run the function
public void Logout(){
Login login = new Login();
login.Show();
if (Application.Current.Windows.Count > 1) {
Application.Current.Windows[0].Close();
}
this.CloseAction();
// _eventAggregator.GetEvent<AppMessageLogout>().Publish();
// _regionManager.Regions.ToList().ForEach((r) => r.RemoveAll());
}
But when i retry to login, my views viewmodels (the usercontrols FileTree and FileDetails) are called two times (debugging the constructor method).
The previously commented lines are two attempts to solve the issue without success:
using a publish/subscribe command with a Disposable in the UserControl (I disposed only the register commands in the viewmodel since there isn't a Close() in a UserControl)
trashing all the views in the regionManager to avoid garbageCollection. Altought i guess this is useless since, as i read online, the parentWindow of the views is the MainWindow and when it close also the views do
The ViewModels are all autowired with Prism in the xaml files.

WPF MVVM How to create new Window instance with no input data

In WPF (MVVM) when I create new instance of window (view) it has no entry data - but when I enter some data, close window and reopen it contains the same data as window was closed with. How to provide "fresh" window (with blank fields which need to be fulfilled) instance each time?
I've tried many things and right now my class "ViewService" looks like this.
public class ViewService : IViewService
{
public void Show<T>()
{
try
{
T window = Activator.CreateInstance<T>();
var view = window as Window;
view.Show();
}
catch (Exception)
{
}
}
public void ShowDialog<T>()
{
try
{
T window = Activator.CreateInstance<T>();
var view = window as Window;
view.ShowDialog();
}
catch (Exception)
{
}
}
Thank you very much for your help.
PS. I use SimpleIoC container to register viewmodels.
Simpleioc will give you a singleton for any type and hence the same instance of a given viewmodel each time.
Hence, your problem.
Either.
Use a different dependency injection system which is more sophisticated and will return a new instance each time.
Or.
Don't inject your window viewmodels at all.

Twitch Bot Form wont Initialize

I'm trying to make a chat bot for twitch and i want to make it in a Form so its very user friendly, i got the twitch communication done but now my form wont initialize. Please help.
namespace TwitchBotForm
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
IrcClient irc = new IrcClient("irc.twitch.tv", 6667, "z_bot909", "oauth:dn2tixd1xd7krggyn49ztw08hmfjea");
irc.joingRoom("z_dog909");
irc.sendChatMessage("Startup Complete");
while (true)
{
string message = irc.readMessage();
string[] splitMessage = message.Split('#');
if (message.Contains("!info"))
{
irc.sendChatMessage("Please Keep all commands LowerCase I made this bot Myself and i think its pretty cool. do !Help for Commands");
}
if (message.Contains("!me"))
{
irc.sendChatMessage(splitMessage[1].Split(':')[0]); //Username
}
}
}
}
}
You should not put this infinite loop in constructor of your form.
Check this article on how to run background thread with windows forms.

How to access UserControl's DataContext from another UserControl?

I'm working on a legacy application that's written using Silverlight 5, The application contains lot's of anti-patterns and bad practices. I'm responsible for adding real-time interactions (such as notification) using SingalR.
By the way, They're using these WCF RIA Services for interacting with authentication.
They have a Main page, this page is the place where I'm getting user's notification and show them for logged in users:
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
//...
}
}
So as you can see I didn't set DataContext property as long as user is logged in, I need to set MainPage's DataContext after a user logs in to application, So I have to do that in LoginOperation_Completed inside LoginForm page:
public partial class LoginForm : StackPanel
{
private LoginRegistrationWindow parentWindow;
private LoginInfo loginInfo = new LoginInfo();
public LoginForm()
{
InitializeComponent();
//...
}
private void LoginOperation_Completed(LoginOperation loginOperation)
{
if (loginOperation.LoginSuccess)
{
// Here I need to access MainPages's DataContext property and set it with my ViewModel
}
}
}
Now my question is that, how can I set MainPage's DataContext property inside another class (in this case LoginFrom)?
I have also tried to give an ID to my MainPage user control and access it like this:
mainPage.DataContext = new NotificationItemViewModel();
But the compiler gives me this error:
The name 'mainPage' does not exist in the current context
I finally figured out How to solve my question, There is a simple way to achieve this, I should have created the static instance of the MainPage class in the class itself:
public partial class MainPage : UserControl
{
public static MainPage Instance { get; private set; }
public MainPage()
{
InitializeComponent();
Instance = this;
}
}
Now I can access to the MainPage's DataContext this way:
MainPage.Instance.DataContext = new NotificationItemViewModel();
You need to name your MainPage UserControl where you pasted it in LoginForm XAML. Not in the definition of MainPage.

Swapping MainWindows in WPF?

I have two "MainWIndows". A Login screen and the actual Content Main Window. This is the process in which i want to happen.
User starts application
Clicks Login Button on the Login Window
Initialize the Content Window
Wait until all my lists and Data have been gathered, parse, and added to ListViews
Close the Login Window and show the Main Window. (Make MainWindow the main Window)
I am having issues actually hiding the main window, but i still need to be able to initialize it so i can gather all my data.
I added this to my App.xaml:
<Application.MainWindow>
<NavigationWindow Source="MainWindow.xaml" Visibility="Hidden"></NavigationWindow>
</Application.MainWindow>
Here is my some of my LoginWindow code:
// Login complete, load the MainWindow Data
MainWindow mainWindow = new MainWindow();
mainWindow.setLoginWindow = this;
mainWindow.InitializeComponent(); //mainWindow.Show();
And the code i am using in the MainWindow:
public partial class MainWindow : MetroWindow
{
Window LoginWindow;
public Window setLoginWindow { get { return LoginWindow; } set { LoginWindow = value; } }
public MainWindow()
{
InitializeComponent();
// Hide the window to load Data, then on completion, close LoginWindow and show MainWindow: ::: LoginWindow.Close();
LoadData();
}
public void LoadData()
{
// Add player's to list ....
// Done loading data, show the window
LoginWindow.Close();
this.Visibility = Visibility.Visible;
}
}
The Question
How would i do this properly? Also, i want to keep the Focus on the LoginWindow until the MainWIndow has been shown.
(off the top of my head so watch for syntax errors etc...)
Edit the App.xaml and do this:
Startup="StartUp"
Then edit the App.xaml.cs and add a StartUp event like so:
private void StartUp(object sender, StartupEventArgs args)
{
...
}
Then inside you can call your login window and then start your main window after that.
var login = new LoginWindow();
if(login.ShowDialog()!=true)
{
//login failed go away
return
}
var mainWin = new MainWindow();
mainWin.Show();
I think the problem is that you are putting you logic in the MainWindow. Try putting it in the static Main() method or in the class App: Application class.
Here is a code project where he is doing something similar for a splash screen:
http://www.codeproject.com/Articles/38291/Implement-Splash-Screen-with-WPF
Here is a tutorial for working with the App.xaml.cs
http://www.wpf-tutorial.com/wpf-application/working-with-app-xaml/

Categories