MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Связанные окна WPF"
Answer 1152725
Если два "окна" должны двигаться вместе, то проще всего их сделать не отдельными окнами, а элементами управления на одном физическом окне.
- Создаем полностью прозрачное родительское окно со свойствами
WindowStyle="None" AllowsTransparency="True" Background="Transparent"
- В нем создаем window1 и window2 допустим как Grid-ы
- Воссоздаем в родительском окне нужный функционал обычного окна (перетаскивание за заголовок, изменение размера рамкой, кнопки сворачивания-разворачивания-закрытия)
В результате это выглядит как два окна, которые перемещаются вместе. Пример (у меня реализовано только перетаскивание за заголовок и кнопка закрытия):
<Window x:Class="WpfTest.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" WindowStyle="None" AllowsTransparency="True" Background="Transparent" Height="450" Width="600" Loaded="Window_Loaded"> <Grid x:Name="grid"> <Grid x:Name="window1" HorizontalAlignment="Left" Width="250" Margin="0,0,0,0" VerticalAlignment="Stretch" Background="AliceBlue"> <Button x:Name="bClose" Content="X" HorizontalAlignment="Right" Height="36" VerticalAlignment="Top" Width="36" Margin="0,0,0,0" Click="Button_Click" /> <Label x:Name="labelTitle" Content="Window 1" HorizontalAlignment="Stretch" Height="36" Margin="0,0,36,0" VerticalAlignment="Top" > <Label.Background> <SolidColorBrush Color="{DynamicResource {x:Static SystemColors.ActiveCaptionColorKey}}"/> </Label.Background> </Label> <RadioButton Content="On" HorizontalAlignment="Left" Height="22" Margin="25,60,0,0" VerticalAlignment="Top" Click="On_Click"/> <RadioButton Content="Off" HorizontalAlignment="Left" Height="22" Margin="70,60,0,0" VerticalAlignment="Top" IsChecked="True" Click="Off_Click"/> </Grid> <Grid x:Name="window2" HorizontalAlignment="Left" Height="200" Margin="251,0,0,0" VerticalAlignment="Top" Width="250" Background="AliceBlue" > <Label Content="Window 2" HorizontalAlignment="Left" Height="27" Margin="0,0,0,0" VerticalAlignment="Top" Width="120"/> </Grid> </Grid> </Window>
using System; using System.Collections.Generic; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Interop; using System.Runtime.InteropServices; using System.Windows.Media; namespace WpfTest { public partial class MainWindow : Window { [DllImport("user32.dll", SetLastError = true)] static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect); const uint HTCAPTION = 2; const uint HTNOWHERE = 0; const uint WM_NCHITTEST = 0x0084; const uint WS_OVERLAPPED = 0x00000000; const uint WS_CAPTION = 0x00C00000; const uint WS_SYSMENU = 0x00080000; const uint WS_THICKFRAME = 0x00040000; const uint WS_MINIMIZEBOX = 0x00020000; const uint WS_MAXIMIZEBOX = 0x00010000; const uint WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX; static int GET_X_LPARAM(IntPtr lp) { short loword = (short)((ulong)lp & 0xffff); return loword; } static int GET_Y_LPARAM(IntPtr lp) { short hiword = (short)((((ulong)lp) >> 16) & 0xffff); return hiword; } [StructLayout(LayoutKind.Sequential)] public struct RECT { public int left, top, right, bottom; } //обработка координат мыши для неклиентской области IntPtr HitTestNCA(IntPtr hWnd, IntPtr wParam, IntPtr lParam) { Point ptMouse = new Point(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); RECT rcWindow; GetWindowRect(hWnd, out rcWindow); if (ptMouse.Y >= rcWindow.top && ptMouse.Y < rcWindow.top + labelTitle.ActualHeight && ptMouse.X>= rcWindow.left && ptMouse.X < rcWindow.left + labelTitle.ActualWidth) { return (IntPtr)HTCAPTION; } else { return (IntPtr)HTNOWHERE; } } //обработчик сообщений для окна private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { IntPtr lRet = IntPtr.Zero; if (msg == WM_NCHITTEST) { //обработка нажатий мыши lRet = HitTestNCA(hwnd, wParam, lParam); if (lRet != (IntPtr)HTNOWHERE) { handled = true; } } return lRet; } public MainWindow() { } private void Window_Loaded(object sender, RoutedEventArgs e) { WindowInteropHelper h = new WindowInteropHelper(this); HwndSource source = HwndSource.FromHwnd(h.Handle); source.AddHook(new HwndSourceHook(WndProc));//регистрируем обработчик сообщений window2.Visibility = Visibility.Hidden; } private void Off_Click(object sender, RoutedEventArgs e) { window2.Visibility = Visibility.Hidden; } private void On_Click(object sender, RoutedEventArgs e) { window2.Visibility = Visibility.Visible; } private void Button_Click(object sender, RoutedEventArgs e) { this.Close(); } } }
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.