I've made a WPF application and one of my windows is required to go fullscreen, however I'm trying to get it so that if the user drags the window to another monitor it will automatically resize to suit that monitor.
I've tried the previewmouse up down events, mouse up down events to set a bool that the window is being dragged to prevent the code from executing, however this does not appear to work and the window is still trying to resize itself as its being dragged and the mouse is down (as if mousedown is being set to false)
The code that resizes the window is in the window located changed event
Is there any other ways that can effectively detect that the mouse is down and dragging the window to another monitor before executing the code to resize it to suit?
Whilst the user is dragging the window I dont want the code to resize it to be executed, once the user has finished dragging the window, the code to resize the window to the new screen should be executed.
Currently I cant get the code to run after the window has finished moving.
Upon further investigation, no mouse up events are fired after the mouse is released on the title border.
You can override OnPreviewMouseMove for any UI element.
protected override void OnPreviewMouseMove(MouseEventArgs e)
Then using the event args of that handler (of type MouseEventArgs) - you check if the left mouse button is pressed (indicating a drag).
e.LeftButton == MouseButtonState.Pressed
When you start dragging a maximized Window, the size changes. This is how Windows behaves and is natural to a user. On end of drag you can just set the state back to maximized.
Application.Current.MainWindow.WindowState = WindowState.Maximized;
Did you checked this event ? Sounds like what you need.
https://msdn.microsoft.com/en-us/library/system.windows.window.locationchanged%28v=vs.110%29.aspx
Related
I am currently using MSCharts in one of my windows forms. One of the quirky things about MSCharts is that you cannot trigger a MouseWheel event in the chart unless the chart has focus. To combat this, most people are saying that one should add a MouseEnter event to the chart and then Focus() the chart to allow one's MouseWheel events to fire (see here: Enabling mouse wheel zooming in a Microsoft Chart Control).
Let's say that I pull up a completely different window (call it Window A) that just so happens to be partially in front of my chart (call it window is Window B). If I accidentally move the mouse over the chart in Window B for even 10 milliseconds, Window B will take focus and Window A will be placed behind it, which is incredibly frustrating.
I've explored different options.
Setting Window B's TopMost property to true. The problem with this is that the user has to either close the window or minimize it to hide it. If there are a lot of windows up, it seems to be just as frustrating as the initial issue.
Instead of giving the MouseEnter event the ability to Focus(), let the MouseClick or MouseHover event to Focus(). The problem with MouseClick is that the user will always have to click on the chart first to zoom, which isn't bad, but can be annoying. MouseHover is okay, but the time that the event considers to be a hover is really short.
In the end, I want it so that I can put my mouse over the chart and scroll in without having to do anything (mouse clicks, or anything else). In addition to this, I don't want the form that contains the chart to jack the focus back to it if I accidentally move my mouse over it for just a second.
EDIT:
It seems that according to #TaW, the chart doesn't need focus to trigger MouseWheel events in Window 10. This is not the case in Windows 7, unfortunately.
This may seem slightly hacky, but it works in this case:
This works through the use of the FindForm method. I never knew it was a thing until now. You can read more about it here: https://msdn.microsoft.com/en-us/library/system.windows.forms.control.findform(v=vs.110).aspx
myChart.MouseEnter+= delegate(object sender, EventArgs args) //add a mouse enter event to your chart
{
if (!chart.Focused) //if chart isn't focused
{
if (chart.FindForm().ContainsFocus) //check if the form the chart is in contains focus
chart.Focus(); //if the chart isn't focused, but the form is focused, focus on the chart
}
};
This will still give the chart focus when you move your mouse into it and it will not allow the form that contains the chart to jack the focus from the form you're in.
I have a Window that gets resized by code upon an external event. The external event indicates that new data is available and the form needs to resize slightly to fit the new data. This works fine in the normal case BUT when holding down the mouse of the window title bar, the window is resized back to the original size after releasing the mouse. Let me explain:
Window has size X
Pressing mouse down on the window title bar
External event is received, Window is resized to Y. This works fine and the window is correctly resized and redrawn.
Releasing mouse on the window title bar causes an ResizeEnd evnet to be triggered which resizes the window back to X.
How do I prevent the window from being resized back to X in ResizeEnd event in the best way?
I have a "borderless" window in WPF. It can be dragged from any part of the window that does not handle the Click event, using this code:
// Drag the window:
private void GlassWindow_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton != MouseButton.Left) return;
if (AllowDrag) DragMove();
}
(Note: AllowDrag is always set to true in this case)
This code works fine, except that when I click on the window and hold down the left mouse button, without moving the cursor (= not dragging the window), the window freezes for about 2-3 seconds (i.e. all animations pause, progressbar stops moving). This behaviour is consistent, and does not happen when I click on a button or when I drag the window, only when I hold left click.
Is there any solution for this or is this intended windows behavior?
EDIT: Things that don't solve the problem:
https://stackoverflow.com/a/3275712/2719183
https://stackoverflow.com/a/5494769/2719183
http://www.codeproject.com/Articles/11114
if (AllowDrag) DragMove();
DragMove() is the trouble-maker, it is uses a pretty hacky way to implement the move. And that causes the problem you describe, the WPF team is well-aware of the issue but chose to not fix it. You can read about it in this connect article. Vote if you are not pleased.
So you need to avoid DragMove(). The best way is to do it the way it is normally done, you minimize the risk of reproducing the exact same trouble that way. That requires knowing a little about the way the winapi works. Whenever a window is clicked, Windows sends the WM_NCHITTEST message to ask your app what part of the window was clicked. When you return HTCAPTION, even if you don't have a caption, then Windows takes your word for it and implements what normally happens when you click and drag a window by its caption.
That has been done, you don't have to be an expert in the winapi to get that going. Google "wpf wm_nchittest" to find code. The top hit is an existing SO question, Tergiver's code looks good.
I have tried doublebuffering the form - but while I am dragging the form sides or corners to resize it at runtime, the controls do not update and timer events are not firing, until I stop resizing the form with the mouse.
The form consists of a datagridview contained in a tabcontrol and some sounds playing. Everything runs fine unless I am resizing the window (form) at runtime. This is not the end of the world, but just odd behaviour.
It is as though all events and handling are suspended on the form while the form is being resized, or the resizing event is using up all the processor (which it isn't). Is there a way to force event handling while the user resizes the window form?
As a simple example, the form has a sound that is played every 500ms. If at runtime I drag the bottom corner or a side of the window to resize it, the sound is not played until I stop resizing the window (by either releasing mouse click, or not moving mouse).
I have a windows form in a wpf window, and I'm trying to use DragMove when I click on the windows form, it's a picturebox so I want to be able to drag the window around just by clicking the picture.
I catch my form's mouse down, and raise the wpf window's mouseleftbuttondown event with:
if (e.Button == MouseButtons.Left)
{
MouseDevice mouseDev = InputManager.Current.PrimaryMouseDevice;
MouseButtonEventArgs mouseEvent = new MouseButtonEventArgs(mouseDev, 0, MouseButton.Left)
{
RoutedEvent = MouseLeftButtonDownEvent
};
RaiseEvent(mouseEvent);
}
However whenever I check the InputManager.Current.PrimaryMouseDevice from my handler (or my form's MouseMove handler), the LeftButton's state is "released".
Why is this? I can't figure out a way to force it to be "pressed" since all the properties are read-only.
Or is my approach simply wrong and is not possible? I did also try setting the location of my window on mouse move, but some weird stuff happens where my mouse values keep going back to the previous position.
Thanks!
edit: So I'm manually adjusting the window location, but still hope someone can enlighten me as to why MouseDevice doesn't get pressed on a windows form. The "weird stuff happens..." was just a dumb mistake on my part, I kept resetting the mouse coordinates on mouse move, but realized that my mouse never moves relative to the window since the window is moving too, duh!
A similar issue stumped me for a while: the ButtonState property of MouseButtonEventArgs reflects the real-time state of that button, not a state snapshot taken when the event was raised. I wonder if the same holds true re your accessing LeftButton's state.
Hope this helps,
Ben