I have a WPF application that I have removed the border and default controls by doing the following:
WindowStyle="None" AllowsTransparency="True"
Now I added a MouseDown handler MouseDown="Window_MouseDown" and added the following code to allow me to move my Window around:
private void Window_MouseDown(object sender, MouseButtonEventArgs e)
{
try
{
if (e.ChangedButton == MouseButton.Left)
DragMove();
}
catch (Exception ex) { }
}
But now I have a UserControl that I want to resize to the full size of my Application so to achieve this I created a new Window that is the same size as my MainWindow and placed the UserControl onto it. I create this new Window and set its parent to be my main application like so:
public MyFullScreenWindow()
{
InitializeComponent();
this.Owner = App.Current.MainWindow;
}
I launch this window like so:
MyFullScreenWindow fullScreen = new MyFullScreenWindow();
fullScreenVideo.ShowDialog();
My problem is that I want to still move my whole application around whenever the user clicks and moves this new window. To achieve this I have added an Event to MyFullScreenWindow:
public partial class MyFullScreenWindow: Window
{
static public event EventHandler MouseDownEvent;
public MyFullScreenWindow()
{
InitializeComponent();
this.Owner = App.Current.MainWindow;
}
private void Window_MouseDown(object sender, MouseButtonEventArgs e)
{
if (MouseDownEvent != null)
{
MouseDownEvent(sender, e);
}
}
}
And I handle this event in my MainWindow like so:
MyFullScreenWindow.MouseDownEvent += new EventHandler(MyFullScreenMouseDownHandler);
private void MyFullScreenMouseDownHandler(object sender, EventArgs e)
{
DragMove();
}
But when I click and drag I see that the event is fired off but my whole application does not move like it should. Why is this??
Simply add the following function code only
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
// Begin dragging the window
this.DragMove();
}
move your window where ever you want.
I don't know the context of your problem, but why would you create a new window, "place" it inside the parent one? You can use controls without creating a new window.
It's possible that you are doing this because you need AllowTransparency=false functionality, while showing it in AllowTransparency=true window. (I had this case when working with DirectShow). If you're doing this for custom window chrome, then don't use AllowTransparency - it decreases performance greatly. It's creating picture of every frame and disables GPU acceleration, after all! Instead, you can adapt to CustomChromeWindow project(found on Internets).
Note that you can enable the main window so that it would process messages from underlying window:
public class WindowSecond : Window
{
public WindowSecond()
{
Owner = Application.Current.MainWindow;
MouseDown += delegate
{
// maybe cache it.
IntPtr handle = new WindowInteropHelper(Owner).Handle;
EnableWindow(handle, true);
Application.Current.MainWindow.DragMove();
EnableWindow(handle, false);
};
}
[DllImport("user32")]
internal static extern bool EnableWindow(IntPtr hwnd, bool bEnable);
}
Related
I have a window and a Frame within it. in that Frame, i open many pages which i would like to close by clicking on "Close" button ,
the problem is the page can't see my frame i tried to write in an event a close button in a page method
to execute another event in a main window because it's easy on a main window to see a frame , but it's not working. here is my code in a page
private void closebt_MouseDown(object sender, MouseButtonEventArgs e)
{
var main = new MainWindow();
main.Exitbt_PreviewKeyDown(main.Exitbt, e);
}
and here is a code in a main window
internal void Exitbt_PreviewKeyDown(object sender, MouseButtonEventArgs e)
{
ProjectorFrame.Content = "";
MessageBox.Show("done");
}
Although the message show but it's not close page
please help me.
I don't know why you create another MainWindow instance inside the closebt_MouseDown hander, but I hope the following code would helpful for you:
private void closebt_MouseDown(object sender, MouseButtonEventArgs e)
{
MainWindow main = Application.Current.MainWindow as MainWindow;
if (main != null)
{
main.Exitbt_PreviewKeyDown(main.Exitbt, e);
main.Close();
}
}
Edited:
I supposed that the main Window object of your application is MainWindow, so I thought that the previous code could get your application window close.
But as you commented, Application.Current.MainWindow is different from MainWindow, and the main became null.
Therefore, I think the simple way to get the main Window object is to create the following constructor in your page class to keep the reference:
class YourPageClass
{
public YourPageClass(MainWindow mainWindow)
{
main = mainWindow;
}
private MainWindow main;
(snip)
}
Then, create this instance with passing main Window object:
// somewhere in MainWindow code where instantiate your page object
var page = new YourPageClass(this);
By doing that, you can get the main Window object.
So now, you can close your Window object as follows:
// in YourPageClass code
private void closebt_MouseDown(object sender, MouseButtonEventArgs e)
{
if (main != null)
{
main.Exitbt_PreviewKeyDown(main.Exitbt, e);
main.Close();
}
}
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)
In mdimain_MdiChildActivate the application logic is defined for all child forms
related to GridControl mouseDoubleClick event .
It is working fine for all grid containing child forms but in some case where grid mouseDoubleClick is defined internal for the Child Form.
So, the event is fired twice one from MdiParent and for internal part.
Is there any way such that MdiParent Parent Control event does not fire's for this mouseDoubleClick case comparing/validating the ifexist case for Child Form without changing the code in MDI form.
sample example :
private void MDIMain_MdiChildActivate(object sender, EventArgs e)
{
// code should not work
}
private void MainGridControl_MouseDoubleClick(object sender, MouseEventArgs e)
{
/// Child Form : code should work
}
This approach detects WM_NCHITTEST message sent to your MainGridControl before MdiChildActivate is fired. This can only detect if your mouse is used (Click, DoubleClick) on the MainGridControl but I think it suits in your case.
public class Form1 : Form {
public Form1(){
InitializeComponent();
Load += (s,e) => {
gridProc.AssignHandle(MainGridControl.Handle);
};
}
MainGridProc gridProc = new MainGridProc();
private void MDIMain_MdiChildActivate(object sender, EventArgs e)
{
if(gridProc.HitTestOn) { gridProc.HitTestOn = false; return; }
//code is still run if HitTestOn = false
//.......
}
public class MainGridProc : NativeWindow {
protected override void WndProc(ref Message m){
if(m.Msg == 0x84)//WM_NCHITTEST
{
HitTestOn = true;
}
base.WndProc(ref m);
}
public bool HitTestOn {get;set;}
}
}
I have a main parent winform in which I have implemented some features and that have a number of child windows. Now I want the functionality I have implemented to run also on the child windows.
For instance, in the parent window I am moving an image on the selection of a checkbox. Now, if this checkbox is checked then the image should also move on the all other child windows.
Note: The image moving on the parent window should disapper and should only show on the opend dialogue or child window.
Please suggest if it is possible.
Try using events.
Create an event for the parent form called ImageMoved.
The child forms should subscribe to this event, and when you move the image, you raise the event, then the child forms will know to do their thing.
Lots of different ways to do this. Simple example:
public partial class Form1 : Form {
public event EventHandler ImageMoved;
private void OnImageMoved() {
if (ImageMoved != null)
ImageMoved(this, new EventArgs());
}
private void button1_Click(object sender, EventArgs e) {
OnImageMoved();
}
private void button2_Click(object sender, EventArgs e) {
Form2 f2 = new Form2(this);
f2.Show();
}
}
Then your child forms could look something like this:
public partial class Form2 : Form {
public Form2(Form1 parentForm) {
InitializeComponent();
parentForm.ImageMoved += new EventHandler(parentForm_ImageMoved);
}
void parentForm_ImageMoved(object sender, EventArgs e) {
MessageBox.Show("Image moved");
}
}
You could also create your own EventArgs class if you want to pass more information, such as which image, etc.