I am have trouble using multiple windows in WPF and switching between them using a button. In theory my application should have 2 buttons, one forward and one back each on respectively changing the window to the previous and next window.
Unfortunately I get a Stackoverflow error, through my research I feel that it has something to do with me creating new windows that are creating the window again when the previous window is created, thus making a horrible loop. However I don't know where I can put the window creation code to stop this problem or if there are other ways to fix this.
Here is code for my windows:
First Window
public partial class Presenation_1 : Window
{
Presentation_2 p2 = new Presentation_2();
MainWindow M = new MainWindow();
public Presenation_1()
{
InitializeComponent();
}
private void btnForward_Click(object sender, RoutedEventArgs e)
{
this.Close();
p2.Show();
}
private void btnBack_Click(object sender, RoutedEventArgs e)
{
this.Close();
M.Show();
}
}
Second Window
public partial class Presentation_2 : Window
{
Presentation_3 p3 = new Presentation_3();
Presenation_1 p1 = new Presenation_1();
public Presentation_2()
{
InitializeComponent();
}
private void btnForward_Click(object sender, RoutedEventArgs e)
{
this.Close();
p3.Show();
}
private void btnBack_Click(object sender, RoutedEventArgs e)
{
this.Close();
p1.Show();
}
}
Third Window
public partial class Presentation_3 : Window
{
Presentation_4 p4 = new Presentation_4();
Presentation_2 p2 = new Presentation_2();
public Presentation_3()
{
InitializeComponent();
}
private void btnForward_Click(object sender, RoutedEventArgs e)
{
this.Close();
p4.Show();
}
private void btnBack_Click(object sender, RoutedEventArgs e)
{
this.Close();
p2.Show();
}
}
Fourth Window
public partial class Presentation_4 : Window
{
Presentation_3 p3 = new Presentation_3();
MainWindow M = new MainWindow();
public Presentation_4()
{
InitializeComponent();
}
private void btnForward_Click(object sender, RoutedEventArgs e)
{
this.Close();
M.Show();
}
private void btnBack_Click(object sender, RoutedEventArgs e)
{
this.Close();
p3.Show();
}
}
Thanks in advance
Don't create your Windows before the button is clicked, you can create them in the event handler:
private void btnForward_Click(object sender, RoutedEventArgs e)
{
var p2 = new Presentation_2();
this.Close();
p2.Show();
}
When you create a windows, you create 2 other windows with
new Presentation_X()
This new windows is automaticaly show and itself open 2 other windows.
You can create this windows once in the Mainwindow (auto hide this one), pass the reference in constructor and not close these windows. Quick example (not tested) :
public partial class Presenation_X : Window
{
private Window preview;
private Window next;
public Presenation_X(Window w1, Window w2)
{
this.preview = w1;
this.next = w2;
InitializeComponent();
}
private void btnForward_Click(object sender, RoutedEventArgs e)
{
this.next.Show();
this.Hide();
}
private void btnBack_Click(object sender, RoutedEventArgs e)
{
this.preview.Show();
this.Hide();
}
}
Related
I am trying to make a simple screen share application in C# and found this guide: https://www.c-sharpcorner.com/uploadfile/ulricht/how-to-create-a-simple-screen-sharing-application-in-C-Sharp/ and followed it but it doesn't work i tried it on the same computer and on two different PCs but nothing seems to work
//Host
public partial class ScreenShareHandler : Form
{
RDPSession x = new RDPSession();
public ScreenShareHandler()
{
InitializeComponent();
}
private void ScreenShareHandler_Load(object sender, EventArgs e)
{
}
private void Incoming(object Guest)
{
IRDPSRAPIAttendee MyGuest = (IRDPSRAPIAttendee)Guest;//???
MyGuest.ControlLevel = CTRL_LEVEL.CTRL_LEVEL_INTERACTIVE;
}
private void button1_Click(object sender, EventArgs e)
{
x.OnAttendeeConnected += Incoming;
x.Open();
}
private void button2_Click(object sender, EventArgs e)
{
IRDPSRAPIInvitation Invitation = x.Invitations.CreateInvitation("Trial", "MyGroup", "", 10);
textBox1.Text = Invitation.ConnectionString;
}
private void button3_Click(object sender, EventArgs e)
{
x.Close();
x = null;
}
}
//Client
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
string Invitation = textBox1.Text;// "";// Interaction.InputBox("Insert Invitation ConnectionString", "Attention");
axRDPViewer1.Connect(Invitation, "User1", "");
}
private void button2_Click(object sender, EventArgs e)
{
axRDPViewer1.Disconnect();
}
}
As written in my comments:
Have you hooked up the eventhandlers correctly? If you click on the button in the designer you can go to the Events Tab in the Property-window and check if the Click-event points to the right eventhandler. Another way to check if the correct handler is used is to put a breakpoint inside each handler. Then debug and check if you get into the right method when you click the button. If not you didn't hook up the Eventhandlers correctly.
So I have a Page(Homepage.xaml), when I click a button on this page it opens a prompt(Prompt.xaml).
This prompt is just a Window that I've made and executed using a window.ShowDialog(); method in the Homepage.cs. I've been able to add a little code and when the NO button is clicked the prompt window is closed, now where I'm finding trouble is the YES button.
What I want is for the YES button to take me back to MainWindow, which I've been able to achieve so far, but when it opens the previous Homepage.xaml
is still there and I don't know how to close the Page from the prompt window, if that's even possible?
Another thing is, when the MainWindow opens it kinda pops up, can I make it so that it just lands on the page instead of opening/popping up like a new program?
Heres the Code.
Homepage.cs
public partial class User_Homepage : Page
{
public static Page pager { get; set; }
public User_Homepage()
{
InitializeComponent();
}
public void UserLogoutBtn_Click(object sender, RoutedEventArgs e)
{
var lovmsgb = new Custom_MessageBoxes.LogoutVerification();
lovmsgb.ShowDialog();
}
}
Prompt.cs
public partial class LogoutVerification : Window
{
public LogoutVerification()
{
InitializeComponent();
}
private void YesLogoutBtn_Click(object sender, RoutedEventArgs e)
{
this.Close();
MainWindow window = new MainWindow() { WindowStartupLocation = WindowStartupLocation.CenterScreen};
window.Show();
}
private void NoLogoutBtn_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}
And MainWindow.cs just in case
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void BtnClickP1(object sender, RoutedEventArgs e)
{
mainFrame.Content = new Page1();
}
private void AdminBtn_Click(object sender, RoutedEventArgs e)
{
mainFrame.Content = new Page3();
}
}
To check what button was clicked you should assign DialogResult in your DialogWindow:
private void YesLogoutBtn_Click(object sender, RoutedEventArgs e)
{
DialogResult = true;
this.Close();
}
private void NoLogoutBtn_Click(object sender, RoutedEventArgs e)
{
DialogResult = false;
this.Close();
}
Now make method to call dialog in your MainWindow and pass it as argument to Page1:
private void AskDialog()
{
Dialog dialog = new Dialog();
if (dialog.ShowDialog() == true)
{
mainFrame.Content = null;
}
else
{
// False action
}
}
private void button1_Click(object sender, RoutedEventArgs e)
{
frame.Content = new Page1(AskDialog);
}
In Page1 just call this action after button is pressed:
public User_Homepage(Action askDialog)
{
InitializeComponent();
AskDialog = askDialog;
}
private readonly Action AskDialog;
private void UserLogoutBtn_Click(object sender, RoutedEventArgs e)
{
AskDialog();
}
namespace Pong
{
public partial class Menu : Form
{
public Menu()
{
InitializeComponent();
}
private void pictureBox1_Click(object sender, EventArgs e)
{
}
private void PlayButton_Click(object sender, EventArgs e)
{
PongForm form = new PongForm();
PongForm.Show();
this.Close();
}
private void ExitButton_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
Can someone explain why I'm getting an error? I've had a look online and think it should work. I'm trying to change to a new form on button click.
In this function you should refer form, not PongForm:
private void PlayButton_Click(object sender, EventArgs e)
{
PongForm form = new PongForm();
form.Show();
this.Close();
}
Change "PongForm.Show();" to "form.Show().
To eloborate: you are attempting to call the class, not the instance you created.
to just add to what others have said. you probably don't want multiple of the same forms open. I cant comment or I would have done that instead. hope this solves your problem.
if (Application.OpenForms["PongForm"] != null)
{
Application.OpenForms["PongForm"].WindowState = FormWindowState.Normal;
Application.OpenForms["PongForm"].BringToFront();
}
else
{
PongForm form = new PongForm();
form.Show();
}
I'm new to WPF and couldn't find an answer to to this issue:
I have 3 windows I want to navigate between-
MainWindow -> Window1 -> Window2
On cancel button click on Window2 I want to return to Window1.
I found this code to navigate between 2 windows, but not between 3 as I need:
MainWindow:
private void Window1_Click(object sender, RoutedEventArgs e)
{
Window1 window1 = new Window1();
window1.Show();
this.Hide();
}
Window1:
private void btn_Cancel_Click(object sender, RoutedEventArgs e)
{
Application.Current.MainWindow.Show();
this.Close();
}
private void btn_Window2_Click(object sender, RoutedEventArgs e)
{
Window2 window2 = new Window2();
window2 .Show();
this.Hide();
}
Window2:
private void btn_Cancel_Click(object sender, RoutedEventArgs e)
{
this.Close();
//what should I write to show Window1 again?
}
Here is an example of a navigation service class that holds a stack of navigated windows.
public static class NavigationService
{
static NavigationService()
{
NavigationStack.Push(Application.Current.MainWindow);
}
private static readonly Stack<Window> NavigationStack = new Stack<Window>();
public static void NavigateTo(Window win)
{
if(NavigationStack.Count > 0)
NavigationStack.Peek().Hide();
NavigationStack.Push(win);
win.Show();
}
public static bool NavigateBack()
{
if (NavigationStack.Count <= 1)
return false;
NavigationStack.Pop().Hide();
NavigationStack.Peek().Show();
return true;
}
public static bool CanNavigateBack()
{
return NavigationStack.Count > 1;
}
}
You can use it from your views' code behind :
public void OnNextClicked(object sender, EventArgs args)
{
NavigationService.NavigateTo(new Window2());
}
public void OnPreviousClicked(object sender, EventArgs args)
{
NavigationService.NavigateBack();
}
The static constructor adds the main view started from your App.xaml StartupUri to the navigation stack as the initial view.
If your application has a growing complexity you may also have a look at tools such as prism navigation system.
Change the way you show your windows like this:
private void Window1_Click(object sender, RoutedEventArgs e)
{
Hide();
new Window1().ShowDialog();
ShowDialog();
}
And use the DialogResult property to hide your windows (except the main window):
private void btn_Cancel_Click(object sender, RoutedEventArgs e)
{
DialogResult = false;
}
I have 3 windows and I am able to switch between them fine. The problem i am running into is the windows aren't saving the data when hidden. I think somewhere they are getting disposed, but i'm not sure how. I have a textbox on two windows to test this. It worked fine when there was only two windows, but adding the third created this problem. Here is my main window.
public partial class MainWindow : Window
{
private AutoImport auto;
private DTLegacy dleg;
public MainWindow()
{
InitializeComponent();
}
public MainWindow(AutoImport parent)
{
InitializeComponent();
auto = parent;
}
public MainWindow(DTLegacy parent)
{
InitializeComponent();
dleg = parent;
}
private void btnAutoImport_Click(object sender, RoutedEventArgs e)
{
this.Hide();
if (auto == null) { auto = new AutoImport(); }
auto.Show();
}
private void btnDTLegacy_Click(object sender, RoutedEventArgs e)
{
this.Hide();
if (dleg == null) { dleg = new DTLegacy(); }
dleg.Show();
}
}
Window 1
public AutoImport()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.Hide();
MainWindow main = new MainWindow(this);
main.Show();
}
Window 2
public DTLegacy()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.Hide();
MainWindow main = new MainWindow(this);
main.Show();
}
I'm thinking the answer might be to create a window class of some sort, but i'm not sure what this would look like.
Why are you creating a new MainWindow instance each time? You're currently hiding it, so show it again instead of creating a new one.
Assuming it's the main Window of your application and AutoImport/DTLegacy are "child" windows, one solution would be to pass the MainWindow instance as parameter of the "child" windows, so you can call .Show() easily:
private MainWindow parent;
public AutoImport(MainWindow parent)
{
InitializeComponent();
this.parent = parent;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.Hide();
this.parent.Show();
}