我正在使用带MVVM模式的WPF。
我想通过获取其他控件的坐标来设置新打开的说新窗口位置(左,顶部,宽度,高度),例如基本窗口上的边框说主窗口。 我在主窗口中使用以下代码:
<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按钮启动新窗口说新窗口。 启动新窗口不是问题,但我想将此窗口启动到与主窗口上的边框相同的位置。 新窗口应完全适合主窗口上的边框。
答案 0 :(得分:1)
以下代码解决了您的问题:
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; }
}