手动设置窗口位置wpf mvvm
问题描述:
我正在使用带有MVVM模式的WPF。手动设置窗口位置wpf mvvm
我想通过获取其他控件的坐标动态地设置新打开的说新窗口位置(左,顶部,宽度,高度),说在基础窗口上的边界说主窗口。 我使用下面的代码在主窗口:
<Window x:Class="WpfApplication3.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"
mc:Ignorable="d"
xmlns:local="clr-namespace:WpfApplication3"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MainVM/>
</Window.DataContext>
<DockPanel>
<StackPanel DockPanel.Dock="Left" HorizontalAlignment="Left">
<Button Content="OK" Width="100"></Button>
</StackPanel>
<Border DockPanel.Dock="Top" BorderBrush="Green" Background="Black" BorderThickness="2" >
</Border>
</DockPanel>
</Window>
现在我要启动的新窗口中点击OK按钮,说新窗口。 启动新窗口不是一个问题,但我想启动这个窗口到像主窗口边框一样的位置。 新窗口应该完全适合主窗口上的边框。
答
下面的代码可以解决你的问题:
XAML:
<Grid>
<Border x:Name="Brd" Margin="50,46,0,0" BorderBrush="#FFB82E2E" Background="#FFC7DC42" BorderThickness="5" CornerRadius="5">
<Label Content="a label"/>
</Border>
<Button Content="Button" HorizontalAlignment="Left" Margin="32,15,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>
</Grid>
代码:
private void Button_Click(object sender, RoutedEventArgs e)
{
Window w = new Window();
w.Width = Brd.ActualWidth;
w.Height = Brd.ActualHeight;
Point pt = Brd.PointToScreen(new Point(0, 0));
PresentationSource source = PresentationSource.FromVisual(this);
System.Windows.Point targetPoints = source.CompositionTarget.TransformFromDevice.Transform(pt);
w.Top = targetPoints.Y;
w.Left = targetPoints.X;
w.Show();
}
编辑#1(后用户的请求)
对于纯MVVM,你必须写一个附加行为。我已将所有的东西都放在MainWindow
名称空间下。
用法:
<Window.Resources>
<Window x:Key="NewWindowKey"/>
</Window.Resources>
<Grid>
<Border x:Name="Brd" Margin="50,46,0,0" BorderBrush="#FFB82E2E" Background="#FFC7DC42" BorderThickness="5" CornerRadius="5">
<Label Content="a label"/>
</Border>
<Button Content="Button" HorizontalAlignment="Left" Margin="32,15,0,0" VerticalAlignment="Top" Width="75">
<local:ApplicationBehaviors.WindowPlacementBehavior>
<local:NewWindowToShowParameters NewWindow="{StaticResource NewWindowKey}" TargetVisualName="Brd"/>
</local:ApplicationBehaviors.WindowPlacementBehavior>
</Button>
</Grid>
代码:
public static class ApplicationBehaviors
{
public static NewWindowToShowParameters GetWindowPlacementBehavior(DependencyObject obj)
{
return (NewWindowToShowParameters)obj.GetValue(WindowPlacementBehaviorProperty);
}
public static void SetWindowPlacementBehavior(DependencyObject obj, NewWindowToShowParameters value)
{
obj.SetValue(WindowPlacementBehaviorProperty, value);
}
// Using a DependencyProperty as the backing store for WindowPlacement. This enables animation, styling, binding, etc...
public static readonly DependencyProperty WindowPlacementBehaviorProperty =
DependencyProperty.RegisterAttached("WindowPlacementBehavior", typeof(NewWindowToShowParameters), typeof(ApplicationBehaviors), new PropertyMetadata(null, new PropertyChangedCallback(WindowPlacementChanged)));
private static void WindowPlacementChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Button ctrl = d as Button;
ctrl.Click += ((s, args) =>
{
DependencyObject parent = VisualTreeHelper.GetParent(ctrl);
while ((parent as Window) == null)
parent = VisualTreeHelper.GetParent(parent);
Window rootWindow = (Window)parent;
NewWindowToShowParameters newWindowParams = ((NewWindowToShowParameters)e.NewValue);
Window newWin = newWindowParams.NewWindow;
Border b = (Border) rootWindow.FindName(newWindowParams.TargetVisualName);
newWin.Width = b.ActualWidth;
newWin.Height = b.ActualHeight;
Point pt = b.PointToScreen(new Point(0, 0));
PresentationSource source = PresentationSource.FromVisual(rootWindow);
System.Windows.Point targetPoints = source.CompositionTarget.TransformFromDevice.Transform(pt);
newWin.Top = targetPoints.Y;
newWin.Left = targetPoints.X;
newWin.Show();
});
}
}
public class NewWindowToShowParameters
{
public Window NewWindow { get; set; }
public string TargetVisualName { get; set; }
}
+0
是否有可能在MVVM中? – user2749679
+0
@ user2749679查看更新后的答案 – AnjumSKhan
@Dheeraj这不是重复。 – Kcvin
窗口的定位是一个仅供查看的相关问题,因此您不应该试图在您的ViewModel中的属性中绑定顶部,左侧,宽度,高度 - 相反,请在代码背后执行 – Kcvin
删除我的评论 – Dheeraj