Как разработать собственное окно, которое будет иметь все свойства общего окна, используя WPF - PullRequest
1 голос
/ 10 ноября 2010
 I am going to develop my own window where I'll have my own Caption Buttons 

(свернуть, развернуть, восстановить и закрыть) и все свойства, связанные с этими кнопками, и можно добавить любой элемент управления в заголовок окна.

Предложите мне способ, которым я будупродолжайте, пожалуйста ......

Заранее спасибо

1 Ответ

4 голосов
/ 10 ноября 2010

Мое предложение НЕ делать это.Это не нужно в WPF.

Просто измените шаблон окна, и вы получите то, что просите.

Редактировать: Вот пример.

<ResourceDictionary 
    x:Class="MyNamespace.StyleWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <LinearGradientBrush x:Key="BackgroundBrush" StartPoint="0.5,1" EndPoint="0.5,0">
        <GradientStop Color="#FFEBECEE" Offset="1"/>
        <GradientStop Color="#FFC2C7CD" Offset="0"/>
    </LinearGradientBrush>
    <Style TargetType="{x:Type Border}" x:Key = "MainBorder">
        <Setter Property="Background" Value="#CACDD6" />
        <Setter Property="BorderBrush" Value="#395984" />
        <Setter Property="BorderThickness" Value="0.25" />
        <!--<Setter Property="CornerRadius" Value="10"/>-->
        <Setter Property="Padding" Value="0" />
    </Style>
    <Style TargetType="{x:Type Button}" x:Key="TitleWindowButton">
        <Setter Property="Background" Value="{StaticResource BackgroundBrush}" />
        <Setter Property="BorderThickness" Value="0" />
        <Setter Property="Height" Value="25" />
        <Setter Property="Width" Value="25" />
    </Style>
    <Style x:Key="WindowStyle" TargetType="{x:Type Window}">
        <Setter Property="AllowsTransparency" Value="False" />
        <Setter Property="WindowStyle" Value="None" />
        <Setter Property="Background" Value="Transparent" />
        <Setter Property="ResizeMode" Value="CanResizeWithGrip" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Window}">
                    <Grid>

                        <Border Width="Auto" Height="Auto" Style="{StaticResource MainBorder}" >
                            <DockPanel   
                  HorizontalAlignment="Stretch" Background="Transparent" VerticalAlignment="Stretch">
                                <Border Height="28" Name="border2" BorderThickness="0,0,0,1" BorderBrush="DarkGray" Background="{StaticResource BackgroundBrush}"
                    MouseLeftButtonDown="OnMouseLeftButtonDown" DockPanel.Dock="Top">
                                    <Grid Name="grid1">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="22" />
                                            <ColumnDefinition Width="176*" />
                                            <ColumnDefinition Width="75" />
                                        </Grid.ColumnDefinitions>

                                        <DockPanel HorizontalAlignment="Right" Grid.Column="2">
                                            <Button Style="{StaticResource TitleWindowButton}" Name="m_btnMinimine" Click="m_btnMinimine_Click">
                                                <Image Source="Images/min.png"></Image>
                                            </Button>
                                            <Button Style="{StaticResource TitleWindowButton}" Name="m_btnMaximine" Click="m_btnMaximine_Click">
                                                <Image Source="Images/max.png"></Image>
                                            </Button>
                                            <Button Style="{StaticResource TitleWindowButton}" Name="m_btnClose" Click="m_btnClose_Click">
                                                <Image Source="Images/close.png"></Image>
                                            </Button>
                                        </DockPanel>
                                        <Image Source="{Binding Path=Icon, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" />
                                        <Label Grid.Column="1">
                                            <ContentPresenter ContentSource="Title" RecognizesAccessKey="True" />
                                        </Label>
                                    </Grid>
                                </Border>

                                <AdornerDecorator>
                                    <ContentPresenter />
                                </AdornerDecorator>
                            </DockPanel>

                        </Border>

                        <Line MouseDown="OnSizeNorth" Name="lnSizeNorth" Stroke="Transparent"   
              Cursor="SizeNS" X1="10" X2="{TemplateBinding ActualWidth}"
              Y1="1" Y2="1" StrokeThickness="2"  />

                        <Line MouseDown="OnSizeSouth" Name="lnSizeSouth" Stroke="Transparent" VerticalAlignment="Bottom" 
                   Cursor="SizeNS" X1="1" X2="{TemplateBinding ActualWidth}" 
                  Y1="{TemplateBinding ActualHeight}" Y2="{TemplateBinding ActualHeight}" StrokeThickness="2" />
                        <Line MouseDown="OnSizeWest" Name="lnSizeWest" Stroke="Transparent"
                  Cursor="SizeWE" X1="1" X2="1" Y1="1" Y2="{TemplateBinding ActualHeight}"  StrokeThickness="2" />
                        <Line MouseDown="OnSizeEast" Name="lnSizeEast" Stroke="Transparent" HorizontalAlignment="Right" 
                  Cursor="SizeWE" X1="{TemplateBinding ActualWidth}" 
              X2="{TemplateBinding ActualWidth}" Y1="1" Y2="{TemplateBinding ActualHeight}"  StrokeThickness="2" />

                        <Rectangle MouseDown="OnSizeNorthWest" Name="rectSizeNorthWest" Cursor="SizeNWSE" Fill="Transparent" Width="5" Height="5" VerticalAlignment="Top" HorizontalAlignment="Left" />
                        <Rectangle MouseDown="OnSizeNorthEast" Name="rectSizeNorthEast" Cursor="SizeNESW" Fill="Transparent" Width="5" Height="5" VerticalAlignment="Top" HorizontalAlignment="Right" />
                        <Rectangle MouseDown="OnSizeSouthWest" Name="rectSizeSouthWest" Cursor="SizeNESW" Fill="Transparent" Width="5" Height="5" VerticalAlignment="Bottom" HorizontalAlignment="Left" />
                        <Rectangle MouseDown="OnSizeSouthEast" Name="rectSizeSouthEast" Cursor="SizeNWSE" Fill="Transparent" Width="5" Height="5" VerticalAlignment="Bottom" HorizontalAlignment="Right" />

                    </Grid>
                </ControlTemplate>
            </Setter.Value>

        </Setter>
    </Style>
</ResourceDictionary>

Вам необходимо 3 изображения для кнопок min / max / normal / close (на изображениях они обозначены как Images / min.png, Images/max.png, Images / normal.png, Images / close.png).

Компиляция словаря ресурсов дает класс MyNamespace.StyleWindow, который можно дополнить обработчиками событий:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Runtime.InteropServices;
using System.Windows.Interop;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using System.Windows.Controls;

namespace MyNamespace {
    public partial class StyleWindow {
        private void m_btnClose_Click(object sender, RoutedEventArgs e) {
            Window window = ((FrameworkElement)sender).TemplatedParent as Window;
            if (window != null)
            {
                window.Close();
            }
        }

        private void m_btnMaximine_Click(object sender, RoutedEventArgs e) {
            Window window = ((FrameworkElement)sender).TemplatedParent as Window;
            if (window != null)
            {
                BitmapImage bitmap = new BitmapImage();

                if (window.WindowState == WindowState.Maximized) {
                    window.WindowState = WindowState.Normal;
                    bitmap.BeginInit();
                    bitmap.UriSource = new Uri(@"Images/max.PNG", UriKind.Relative);
                    bitmap.EndInit();
                    ((sender as Button).Content as Image).Source = bitmap;
                } else {
                    window.WindowState = WindowState.Maximized;
                    bitmap.BeginInit();
                    bitmap.UriSource = new Uri(@"Images/normal.PNG", UriKind.Relative);
                    bitmap.EndInit();
                    ((sender as Button).Content as Image).Source = bitmap;
                }
            }
        }

        private void m_btnMinimine_Click(object sender, RoutedEventArgs e) {
            Window window = ((FrameworkElement)sender).TemplatedParent as Window;
            if (window != null)
            {
                window.WindowState = WindowState.Minimized;
            }
        }

        private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Window window = ((FrameworkElement)sender).TemplatedParent as Window;
            if (window != null)
            {
                window.DragMove();
            }

        }

        #region sizing event handlers

        void OnSizeSouth(object sender, System.Windows.Input.MouseButtonEventArgs e) {
            Window wnd = ((FrameworkElement) sender).TemplatedParent as Window;
            if (wnd != null) {
                WindowInteropHelper helper = new WindowInteropHelper(wnd);
                DragSize(helper.Handle, SizingAction.South);
            }
        }

        void OnSizeNorth(object sender, System.Windows.Input.MouseButtonEventArgs e) {
            Window wnd = ((FrameworkElement) sender).TemplatedParent as Window;
            if (wnd != null) {
                WindowInteropHelper helper = new WindowInteropHelper(wnd);
                DragSize(helper.Handle, SizingAction.North);
            }
        }

        void OnSizeEast(object sender, System.Windows.Input.MouseButtonEventArgs e) {
            Window wnd = ((FrameworkElement) sender).TemplatedParent as Window;
            if (wnd != null) {
                WindowInteropHelper helper = new WindowInteropHelper(wnd);
                DragSize(helper.Handle, SizingAction.East);
            }
        }

        void OnSizeWest(object sender, System.Windows.Input.MouseButtonEventArgs e) {
            Window wnd = ((FrameworkElement) sender).TemplatedParent as Window;
            if (wnd != null) {
                WindowInteropHelper helper = new WindowInteropHelper(wnd);
                DragSize(helper.Handle, SizingAction.West);
            }
        }

        void OnSizeNorthWest(object sender, System.Windows.Input.MouseButtonEventArgs e) {
            Window wnd = ((FrameworkElement) sender).TemplatedParent as Window;
            if (wnd != null) {
                WindowInteropHelper helper = new WindowInteropHelper(wnd);
                DragSize(helper.Handle, SizingAction.NorthWest);
            }
        }

        void OnSizeNorthEast(object sender, System.Windows.Input.MouseButtonEventArgs e) {
            Window wnd = ((FrameworkElement) sender).TemplatedParent as Window;
            if (wnd != null) {
                WindowInteropHelper helper = new WindowInteropHelper(wnd);
                DragSize(helper.Handle, SizingAction.NorthEast);
            }
        }

        void OnSizeSouthEast(object sender, System.Windows.Input.MouseButtonEventArgs e) {
            Window wnd = ((FrameworkElement) sender).TemplatedParent as Window;
            if (wnd != null) {
                WindowInteropHelper helper = new WindowInteropHelper(wnd);
                DragSize(helper.Handle, SizingAction.SouthEast);
            }
        }

        void OnSizeSouthWest(object sender, System.Windows.Input.MouseButtonEventArgs e) {
            Window wnd = ((FrameworkElement) sender).TemplatedParent as Window;
            if (wnd != null) {
                WindowInteropHelper helper = new WindowInteropHelper(wnd);
                DragSize(helper.Handle, SizingAction.SouthWest);
            }
        }


        #endregion

        #region P/Invoke and helper method

        const int WM_SYSCOMMAND = 0x112;
        const int SC_SIZE = 0xF000;


        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

        void DragSize(IntPtr handle, SizingAction sizingAction) {
            if (System.Windows.Input.Mouse.LeftButton == System.Windows.Input.MouseButtonState.Pressed) {
                SendMessage(handle, WM_SYSCOMMAND, (IntPtr) (SC_SIZE + sizingAction), IntPtr.Zero);
                SendMessage(handle, 514, IntPtr.Zero, IntPtr.Zero);
            }
        }

        #endregion

        #region helper enum

        public enum SizingAction {
            North = 3,
            South = 6,
            East = 2,
            West = 1,
            NorthEast = 5,
            NorthWest = 4,
            SouthEast = 8,
            SouthWest = 7
        }
    }
        #endregion
}

Этот ресурс должен быть доступен по всему миру.Вы можете ссылаться на него в XAML следующим образом:

...

В моем проекте дизайнер имел тенденцию задыхаться от этой ссылки (возможно, потому что это был проект WinForms с основной частью, составленнойэлементов WPF).Из-за этого нам пришлось устанавливать стиль программно, в выделенном коде, в конструкторе окна:

Style = (Style) FindResource (Constants.DEFAULT_WINDOW_STYLE);

с константойобъявление со значением "WindowStyle".

Вот результат (извиняюсь за пустой контент, но он конфиденциальный): alt text

Я не сказал, что это было довольно ...

...