WPF Child Window Implementation 1. Customize title bar

In form application, there has a component named MDI, which we can use it to show a child window in parent window. But it's a character of form application, WPF not supposes such thing. But sometimes we need to show a child window stuff in wpf application in some special scenarios, the behavior simply like that in form application would be appreciated. Although there doesn't exist MDI,  some decorations for control would help us achieve that goal as well.

Below is a simple example.

1. Create a WPF application, File>Create project>Choose WPF application. And named this app TestApp. Solution prepared as below


After adding needed files the solution is like below


2. The MainWindow is our host window of child windows. Add a canvas as stage for its child windows, add a button that show child window when we click it.

<pre name="code" class="html"><Window x:Class="TestApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="450" Width="600">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="auto"/>
        </Grid.RowDefinitions>
        <Border BorderThickness="2" BorderBrush="Orange" Grid.Row="0">
            <Canvas Name="canvasStage" />
        </Border>
        <Button Grid.Row="1" Content="Show" FontSize="16" Margin="2"
                Background="LightCoral" Click="Button_Click"/>
    </Grid>
</Window>
 

3.Add a class Named LayoutControl.cs, which would implement some common functions and our "child window" would inherit it.

using System.Windows;
using System.Windows.Controls;

namespace TestApp
{
    public class LayoutControl : UserControl
    {
        public static readonly DependencyProperty TitleProperty = DependencyProperty.Register(
            "Title",
            typeof(string),
            typeof(LayoutControl),
            new PropertyMetadata("My Window"));

        public string Title
        {
            get { return (string)this.GetValue(TitleProperty); }
            set { this.SetValue(TitleProperty, value); }
        }

        public LayoutControl()
            : base()
        {
            this.Style = (Style)Application.Current.Resources["ChildWindowStyle"];
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            Button btnClose = this.Template.FindName("closeBtn", this) as Button;
            Button btnMaxi = this.Template.FindName("maxinumBtn", this) as Button;
            Button btnMini = this.Template.FindName("mininumBtn", this) as Button;

            // Close event
            if (btnClose != null)
            {
                btnClose.Click += (s, e) => ((Panel)this.Parent).Children.Remove(this);
            }

            // Maxinum event
            if (btnMaxi != null)
            {
                btnMaxi.Click += (s, e) =>
                    {
                        Panel parent = (Panel)this.Parent;
                        this.Margin = new Thickness(0);
                        this.Height = parent.ActualHeight;
                        this.Width = parent.ActualWidth;
                    };
            }

            // Mininum event
            if (btnMini != null)
            {
                btnMini.Click += (s, e) =>
                {
                    this.Visibility = Visibility.Collapsed;
                };
            }
        }

    }
}


4. We need to create minimum button, maximum button and close button for child window. To implement this, we could create a style, user control could turn to "window" when apply this style. We add this style in App.xaml 

<Application x:Class="TestApp.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml"
             xmlns:common="clr-namespace:TestApp">
    <Application.Resources>
        <Style x:Key="ChildWindowStyle" TargetType="{x:Type common:LayoutControl}">
            <Setter Property="BorderBrush" Value="Silver"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="Height" Value="300"/>
            <Setter Property="Width" Value="400"/>
            <Setter Property="Margin" Value="20"/>
            <Setter Property="Background" Value="#FFE6E6E6"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type common:LayoutControl}">
                        <Border BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}">
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="20"/>
                                    <RowDefinition Height="*"/>
                                </Grid.RowDefinitions>

                                <!--Make window has shadow-->
                                <Rectangle Fill="{TemplateBinding Background}" Grid.RowSpan="2">
                                    <Rectangle.Effect>
                                        <DropShadowEffect BlurRadius="10" ShadowDepth="3"/>
                                    </Rectangle.Effect>
                                </Rectangle>

                                <!--Title bar-->
                                <Grid Grid.Row="0" Background="{TemplateBinding BorderBrush}">
                                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
                                        <!--Minimum button-->
                                        <Button Name="mininumBtn" Content="⚊" BorderThickness="0" Background="Transparent"/>
                                        <!--Maximum button-->
                                        <Button Name="maxinumBtn" Content="⬒" Margin="3,0" BorderThickness="0"
                                            Background="Transparent"/>
                                        <!--Close button-->
                                        <Button Name="closeBtn" Content="✖" Margin="0,0,3,0" BorderThickness="0"
                                            Foreground="Red" Background="Transparent"/>
                                    </StackPanel>
                                </Grid>

                                <TextBlock Text="{TemplateBinding Title}" HorizontalAlignment="Center" VerticalAlignment="Center"/>

                                <ContentPresenter Grid.Row="1"/>
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Application.Resources>
</Application>

5. Add a wpf UserControl named ChildWindow.xaml, we would use it to mock show MDI scenario.

The code in ChildWindow.xaml

<common:LayoutControl x:Class="TestApp.ChildWindow"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" Title="Hello"
             d:DesignHeight="300" d:DesignWidth="300"
             xmlns:common="clr-namespace:TestApp">
    <Grid Background="White">
        <TextBlock Text="I am child window" FontSize="16" Margin="9"/>
    </Grid>
</common:LayoutControl>
The code in  ChildWindow.xaml.cs
namespace TestApp
{
    /// <summary>
    /// ChildWindow.xaml 的交互逻辑
    /// </summary>
    public partial class ChildWindow : LayoutControl
    {
        public ChildWindow()
        {
            InitializeComponent();
        }
    }
}

6. Then we need to show child window in main window, here we design to show it when we click the show button in Main Window

The code in MainWindow.xaml.cs

using System.Windows;

namespace TestApp
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            ChildWindow window = new ChildWindow();
            this.canvasStage.Children.Add(window);
        }
    }
}

Finally, run the app then you can see the results.


Click the Show button


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值