如何开发一个自定义窗口,它将使用WPF具有所有通用窗口的属性

时间:2010-11-10 12:53:34

标签: wpf custom-controls

 I am going to develop my own window where I'll have my own Caption Buttons 

(最小化,最大化,还原和关闭)以及与这些相关的所有属性 按钮,可以在窗口的标题位置添加任何控件。

建议我如何处理它......

提前致谢

1 个答案:

答案 0 :(得分:5)

我的建议是不要这样做。 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张图像(在图像中引用为Images / min.png,Images / max.png,Images / normal.png,Images / close.png)。 / p>

编译资源字典会提供一个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

我没说它很漂亮......