我想知道是否可以限制子窗口仅在父级面板边界内移动的能力?假设我创建了一个单击按钮的子窗口:
<UserControl x:Class="ChildWindowTest.MainPage"
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:Child="clr-namespace:ChildWindowTest"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400" >
<Grid x:Name="LayoutRoot" >
<StackPanel Width="500" Height="500">
<Button Width="100" Height="25" Click="Button_Click" Content="Child Window"/>
</StackPanel>
</Grid>
</UserControl>
<controls:ChildWindow
x:Class="ChildWindowTest.ChildWindow1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
Width="400" Height="300" Title="ChildWindow1" >
<Grid x:Name="LayoutRoot" Margin="2">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
</Grid>
</controls:ChildWindow>
我可以将生成的孩子移动到屏幕左侧,右侧和下侧(剪掉)。我想避免这种情况,基本上设置一个允许移动子窗口的边界(在StackPanel
边界内)
感谢您的任何建议..
答案 0 :(得分:0)
我尽量保持我的解决方案尽可能简单,但实现理想的行为仍然非常具有挑战性。
基本上,如果您单独留下ChildWindow的ControlTemplate,以下代码应该适合您:
private void Button_Click(object sender, RoutedEventArgs e)
{
ChildWindow wnd = new ChildWindow();
wnd.Width = 800;
wnd.Height = 600;
wnd.Title = "Test";
wnd.MouseLeftButtonUp += wnd_MouseLeftButtonUp;
wnd.Loaded += wnd_Loaded;
wnd.Show();
}
private void wnd_Loaded(object sender, RoutedEventArgs e)
{
var wnd = sender as ChildWindow;
myApplicationActualWidth = Application.Current.Host.Content.ActualWidth;
myApplicationActualHeight = Application.Current.Host.Content.ActualHeight;
//This call might be necessary to make sure the visual tree of wnd is constructed and can be inspected
wnd.UpdateLayout();
//wnd is guaranteed to have at least one child here
myRoot = (FrameworkElement)VisualTreeHelper.GetChild(wnd, 0);
myContentRoot = myRoot.FindName("ContentRoot") as FrameworkElement;
//this is the title bar part
myChrome = myRoot.FindName("Chrome") as FrameworkElement;
myChrome.AddHandler(MouseLeftButtonUpEvent, new MouseButtonEventHandler(wnd_MouseLeftButtonUp), true);
myTransform = (myContentRoot.RenderTransform as TransformGroup).Children.OfType<TranslateTransform>().First();
}
private void wnd_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
Point rootMousePosition = e.GetPosition(sender as ChildWindow);
Point contentRootMousePosition = e.GetPosition(myContentRoot);
Point currentOffset = new Point(rootMousePosition.X - contentRootMousePosition.X, rootMousePosition.Y - contentRootMousePosition.Y);
TransformChildWindowToValidPosition(currentOffset);
}
private void TransformChildWindowToValidPosition(Point currentPosition)
{
// handle left side
if (currentPosition.X < 0)
{
myTransform.X = myTransform.X - currentPosition.X;
}
// handle top
if (currentPosition.Y < 0)
{
myTransform.Y = myTransform.Y - currentPosition.Y;
}
// handle right side
if (currentPosition.X + myContentRoot.ActualWidth > ActualWidth)
{
myTransform.X = myTransform.X - (currentPosition.X + myContentRoot.ActualWidth - myApplicationActualWidth);
}
// handle bottom
if (currentPosition.Y + myContentRoot.ActualHeight > ActualHeight)
{
myTransform.Y = myTransform.Y - (currentPosition.Y + myContentRoot.ActualHeight - myApplicationActualHeight);
}
}
private TranslateTransform myTransform;
private FrameworkElement myRoot;
private FrameworkElement myContentRoot;
private FrameworkElement myChrome;
private double myApplicationActualWidth;
private double myApplicationActualHeight;
这段代码基本上不允许你将ChildWindow移到当前SL应用程序的边界之外,但它应该是一块蛋糕,让你的手掌握窗口的“父”控件的尺寸,并重新调整所有边缘的值。
希望我能帮忙......