Preamble
There are dozens of simular Questions to this topic on StackOverflow already and I browsed a lot without finding a suitable answer, that would apply to my problem.
Task
I have a WPF Window in a MVVM pattern, which has quite a lot of buttons that open other windows. I'd like to have most of my windows appear in relation to my buttons (I have a toolbar in the top right corner of my MainWindow and want most of the smaller windows to appear right below my buttons), or at least on the same screen as my MainWindow.
Problem
At first, I thought this wasn't such a big deal and there were plenty of blogs and questions on google to this topic, yet all of them won't work on my project.
I am using the MVVM pattern, which means:
- I can't use
Mouse.GetPosition(ButtonName)
on my Buttons, as the ViewModel doesn't know their names - I can't use
Mouse.GetPosition(sender)
in a Click-Event, as most Buttons use commands. - I also apparently can't use PointToScreen in my view's code behind, as it will cause an exception (this visual object is not connected to a \"PresentationSource\")
- I could use
Mouse.GetPosition(this)
on a MouseMove-Event in my view's code behind and hand it down to my ViewModel, which will update a Property, that I can use in my Commands when creating the window, but I don't like the idea of having to update a property permanently. Also without PointToScreen I can't set the point in relation to my screen. - I can't use any WinForms references, as this would cause conflicts in my current project
- Additional to Buttons, I also host a UserControl with Hyperlinks in my MainWindow, which open additional windows, that should be in relation to the hyperlinks.
Research
there are quite a few different answers to a question here, but none of them did work for me.
As my ViewModel doesn't know the XAML elements I can't simply access by point notation as suggested here
- My ViewModel doesn't know a WorkingArea, so I couldn't even get my window to appear on the same screen as my MainWindow as demonstrated here
- As most of the other answers, this one seems like it won't work in a ViewModel
Question
I've spent quite some time on a problem, that rather seemed trivial at first, already. Since most questions I've viewed so far seem to target windows without MVVM, what would be the proper approach in a ViewModel to set the location of a window to either my mouse coordinates or the coordinates of a clicked button?
edit: MouseDownEvent as requested in Comments: Xaml:
<Window x:Class="MySampleProject.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MySampleProject"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525"
MouseDown="Window_MouseDown">
C#:
private void Window_MouseDown(object sender, MouseEventArgs e)
{
if (m_oDataContext != null)
{
m_oDataContext.MouseTest(Mouse.GetPosition(this));
}
}
oDataContext is my ViewModel. My MouseTest() is currently empty. I did set a breakpoint at the first bracket. The breakpoint is only reached when left-clicking within my window, not within one of its hosted controls.