I want display a window only one time. When the user click on this button:
private void Notification_Click(object sender, RoutedEventArgs e)
{
NotificationSettings notifications = new NotificationSettings();
notifications.ShowDialog();
}
this will create a new window, I want that if there is already a window opened the user can't open a new one. There is an option in xaml for tell to compiler this? I remember the vb.net with windows form that allow to set the option to show only one windows at time.
Thanks.
Just hold a reference to your window in a field/property and check if it's Visisble already.
well I am not sure what is NotificationSettings exactly but for a window you can create a bool flag to mark when the window is opened and closed, check this code:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
bool WindowFlag = false;
private void button_Click_1(object sender, RoutedEventArgs e)
{
Window TestWindows = new Window();
TestWindows.Closing += TestWindows_Closing;
if (WindowFlag == true)
{
MessageBox.Show("The Window is already opened");
}
else
{
TestWindows.Show();
WindowFlag = true;
}
}
private void TestWindows_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
WindowFlag = false;
}
}
Related
I have a Main Form with a MenuStrip on it, and I use that MenuStrip to open new owned Forms like so:
var target = new Target();
target.Owner = this;
target.Show();
This works exactly how I want it to: the Forms are always shown in front of the Main Form.
The issue that I run into is that, when one of these owned Forms has the focus, I can't access the MenuStrip via keyboard. I'd like CTRL+S to trigger the Save functionality, the same as it does when the Main Form has the focus.
Is this possible? Is there a better way to approach this?
Sorry for the delay, but if you're still having issues or looking for a different method, see below.
In your MainForm:
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
ChildForm child = new ChildForm();
// KeyPreview can be set in the properties of the child form instead
child.KeyPreview = true;
child.KeyPressed += Child_KeyPressed;
child.ShowDialog();
}
private void Child_KeyPressed(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.S)
{
// Save Pressed
}
}
}
and then in your Child Form:
public partial class ChildForm : Form
{
public event EventHandler<KeyEventArgs> KeyPressed;
public ChildForm()
{
InitializeComponent();
}
private void Child1_KeyUp(object sender, KeyEventArgs e)
{
KeyPressed?.Invoke(sender, e);
}
}
Thanks to Troy Mac1ure for the direction. Here's the solution that lets me use the ShortCutKeys from the main menu.
ownedForm.KeyPreview = true;
ownedForm.KeyDown += OwnedForm_KeyDown;
private void OwnedForm_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control)
{
foreach (ToolStripMenuItem menuItem in menu.Items)
{
foreach (ToolStripMenuItem item in menuItem.DropDownItems.OfType<ToolStripMenuItem>())
{
if (item.ShortcutKeys == e.KeyData)
{
item.PerformClick();
return;
}
}
}
}
}
This doesn't handle Alt menu activation, but Paint.NET doesn't handle that either, so I view that as a nice-to-have.
I have multiple windows. My LoginWindow has to validate the user. If this window is canceled the complete application should shutdown. If the user enter the correct login, the LoginWindow should be closed and the MainWindow open.
Question:
My problem is at the yellow diamond: How to determine the state of the login process?
That is my current state.
public partial class App : Application
{
[STAThread]
public static void Main()
{
var app = new App();
var login = new LoginWindow();
if (app.Run(login) == 1) //<-- Problem: How to get the state from login?
{
var mainapp = new MainWindow();
app.Run(mainapp);
}
}
}
I tried to get an exitcode from the loginwindow by using Application.Current.Shutdown(1); but it cause an InvalidOperationException on app.Run(mainapp);, because Shutdown closes the complete application.
Environment.Exit() terminates this process and gives the underlying operating system the specified exit code.
But a window has no "return value". You could handle the Closed event for the LoginWindow and check whether a property of thw window itself, or its view model, has been set. Please refer to the following example.
public class Program
{
private static readonly App app = new App() { ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown };
[STAThread]
public static void Main()
{
LoginWindow login = new LoginWindow();
login.Closed += Login_Closed;
app.Run(login);
}
private static void Login_Closed(object sender, EventArgs e)
{
LoginWindow loginWindow = (LoginWindow)sender;
loginWindow.Closed -= Login_Closed;
if (loginWindow.LoggedIn)
{
MainWindow mainWindow = new MainWindow();
app.MainWindow = mainWindow;
app.ShutdownMode = System.Windows.ShutdownMode.OnMainWindowClose;
mainWindow.Show();
}
}
}
public partial class LoginWindow : Window
{
public LoginWindow()
{
InitializeComponent();
}
public bool LoggedIn { get; private set; }
private void Login_Click(object sender, RoutedEventArgs e)
{
//if (authenticate)...
LoggedIn = true;
Close();
}
private void Cancel_Click(object sender, RoutedEventArgs e)
{
LoggedIn = false;
Close();
}
}
I found a smart solution. A Window with return value is called "Dialog".
App.xaml.cs
[STAThread]
public static void Main()
{
var app = new App() { ShutdownMode = ShutdownMode.OnExplicitShutdown };
if (new LoginWindow().ShowDialog() ?? false == true)
app.Run(new MainWindow());
}
LoginWindow.xaml.cs
private void OnLoginClick(object, EventArgs)
{
this.DialogResult = true;
}
private void OnCancelClick(object, EventArgs)
{
this.DialogResult = false;
}
To exit the whole application use "Application.exit();" and to open the main windows create object of that form then use "object.Show()" and "this .hide()" to hide the login form.
For example:
Assume the query i.e. stored procedure like:
Create procedure dbo.usercheck
(
#userid nvarchar,
#password nvarchar
)
As
Select username from login table
C# code:
SqlCommand com=new
SqlCommand("dbo.usercheck","connection");
If(com.executescalar()==null)
{
Application.exit();
}
else
{
Mainform f=new Mainform();
f.show();
this.hide();
}
You can write the "Application.exit();" statement in cancel button's click event to close the application whenever you want to close whole application when clicked on cancel button of login form.
When user enters wrong user id or password then you can show the error message instead exit the application.
I would use the following code:
Declare a bool variable to check if user closed the app or if it was closed from your code:
bool userClosedForm = false;
Then inside the Close button add this line, after the code you already had there:
private void btnClose_Click(object sender, EventArgs e)
{
//your code
userClosedForm = true;
}
Add a Form_Closed event where you check the value of the variable:
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
if (userClosedForm == true) Application.Exit();
else
{
//your code to open the next form if the user logged in and you closed the form from code
}
}
Hope this helps ^^
I am building a game. I have a Menu page, with a "Start" button. I would like to know how I can make the button direct the user to a new page with the game. I thought of simply changing all buttons' and labels' visibility to false, but that would be very messy. I thought of closing the form and reopening a new one as said here:
http://social.msdn.microsoft.com/Forums/windows/en-US/936c8ca3-0809-4ddb-890c-426521fe60f1/c-open-a-new-form-and-close-a-form?forum=winforms
Like this:
public static void ThreadProc()
{
Application.Run(new Form());
}
private void button1_Click(object sender, EventArgs e)
{
System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(ThreadProc));
t.Start();
this.Close();
}
but when I click the button, you can see the form closing and reopening again, and it doesn't even reopen at the same coordinates.
Is there any way to do such a thing? I want it to move from page to page as it would if this was a website. Is this possible? If so how? Thanks in advance :-)
Use UserControls for every view you need and then switch between them in your code by adding/removing them to/from your form.
Example: The start-page is a UserControl containing the button that starts the game. The game UI is another UserControl that contains all the logic and visuals for your game.
You could then use something like he following:
public class StartView : UserControl
{
...
private void btnStart_Click(object sender, EventArgs e)
{
// Raise a separate event upon the button being clicked
if (StartButtonPressed != null)
StartButtonPressed(this, EventArgs.Empty);
}
public event EventHandler<EventArgs> StartButtonPressed;
}
public class GameView : UserControl
{
...
}
public UserControl SwitchView(UserControl newView)
{
UserControl oldControl = null;
if (this.Controls.Count > 0)
{ oldControl = (UserControl)this.Controls[0];
this.Controls.RemoveAt(0);
}
this.Controls.Add(newView);
newView.Dock = DockStyle.Fill;
return oldControl;
}
You can now create the start view in Form_Load:
public void Form_Load(object sender, EventArgs e)
{
StartView v = new StartView();
v.StartButtonPressed += StartButtonPressed;
SwitchView(v);
}
The event handler that reacts to the start button being pressed would do this:
public void StartButtonPressed(object senderView, EventArgs e)
{
GameView v = new GameView();
UserControl old = SwitchView(v);
if (old != null)
old.Dispose();
}
I´m programming a simple thing in C# and WPF. I have a MainWindow with a button. If I trigger the button it opens a secon window:
private void btnF4_Click(object sender, RoutedEventArgs e)
{
SecondWindow second = new SecondWindow();
second.Show();
}
Naturally if I trigger the button three or four times, I have three or four windows open. I don´t want to use ShowDialog(), but I want to open my second window only once. I mean if I trigger the button and the window is already open, should nothing happen.
Thank you!
Make second an instance variable to the parent window class and only create a new window if it hasn't been created.
Of course you need to make sure to null the instance variable when the second window is closed.
public class ParentWindow ...
{
private SecondWindow m_secondWindow = null;
....
private void btnF4_Click(object sender, RoutedEventArgs e)
{
if (m_secondWindow == null)
{
m_secondWindow = new SecondWindow();
m_secondWindow.Closed += SecondWindowClosed;
m_secondWindow.Show();
}
}
public void SecondWindowClosed(object sender, System.EventArgs e)
{
m_secondWindow = null;
}
}
This might be shortened to the following:
public class ParentWindow ...
{
private SecondWindow m_secondWindow = null;
....
private void btnF4_Click(object sender, RoutedEventArgs e)
{
if (m_secondWindow == null)
{
m_secondWindow = new SecondWindow();
}
m_secondWindow.Show();
}
}
However, I'm never sure whether you can actually "reopen" a window that was closed before. If you need to initialize the window all over upon reopening, use the first code. If you can live with the window starting up showing the previous content, use the second.
Declare SecondWindow in Parent Window class instead of a method.
public class MainWindow : Window {
SecondWindow second = new SecondWindow();
private void btnF4_Click(object sender, RoutedEventArgs e) {
if (!second.IsActive) {
second.Show();
}
}
}
Declaring second in the method makes the second window local to the method, which means every time you click the button it will create a new instance of that class (window)
I'd like to generate a modeless dialog box, whenever I close the box and want to open it again I am getting an error saying
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'TransactionHistoryDialog'.
at System.Windows.Forms.Control.CreateHandle()
here is my code for creating the modeless dialogbox
public partial class TransactionHistoryDialog : Form
{
private static TransactionHistoryDialog instance;
private TransactionHistoryDialog()
{
InitializeComponent();
}
public static TransactionHistoryDialog CreateForm()
{
if (instance == null)
{
instance = new TransactionHistoryDialog();
}
return instance;
}
private void TransactionHistoryDialog_FormClosing(object sender, FormClosingEventArgs e)
{
instance = null;
}
private void buttonClose_Click(object sender, EventArgs e)
{
instance = null;
}
private void buttonTransactionHistoryClose_Click(object sender, EventArgs e)
{
this.Dispose();
}
}
then in my main form whenever the transactionHistory button is clicked transaction dialog shows up : here is my code for event of clicking transaction button
private void buttonTransferHistory_Click(object sender, EventArgs e)
{
TransactionHistoryDialog transactionHistory = TransactionHistoryDialog.CreateForm();
transactionHistory.updateTextBox();
transactionHistory.Show();
}
I have search a lot, but could not find where the problem is. can any one please give me some hints ?
Because closing the Window disposes it. You need to create a new one after it has closed, you cannot show the same Window after it has closed. If you want to show the same one don't close it and in a handler set Visibility to Hidden instead then add another method, e.g. UnHide(), set it back to Visible when wanting to show the same instance again.
I prefer just creating a new one:
TransactionHistoryDialog openTransactionHistoryDialog;
private void buttonTransferHistory_Click(object sender, EventArgs e)
{
if(openTransactionHistoryDialog == null)
{
openTransactionHistoryDialog = new TransactionHistoryDialog();
openTransactionHistoryDialog.updateTextBox();
openTransactionHistoryDialog.Closed += OnTransactionHistoryDialogClosed;
}
openTransactionHistoryDialog.Show();
}
private void OnTransactionHistoryDialogClosed(object sender, EventArgs e)
{
openTransactionHistoryDialog = null;
}
UPDATE: There is an "official" example of a modeless dialog box at the bottom of this page: http://msdn.microsoft.com/en-us/library/aa969773(v=vs.110).aspx.