user2116780
user2116780

Reputation:

Add X Close Button in WPF

I'm new in WPF and I need to make a button (X) to simulate the X button in the form. First I set WindowStyle="None". Then make a Rectangle:

<Rectangle Height="16" HorizontalAlignment="Left" Margin="482,4,0,0" Name="x_btn" Stroke="#00000000" VerticalAlignment="Top" Width="17" MouseEnter="x_btn_MouseEnter" MouseLeftButtonUp="x_btn_MouseLeftButtonUp">
    <Rectangle.Fill>
        <ImageBrush ImageSource="/Red%20Crescent;component/Images/x_btn.png" />
    </Rectangle.Fill>            
</Rectangle>

After this I want to change the Background Image OnMousEnter event behind code:

private void x_btn_MouseEnter(object sender, MouseEventArgs e)
{           
}

private void x_btn_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    this.Close();
}

Please help as fast as you can.

Note: I tried to use a Button but it's leave a border and i don't want that.

Upvotes: 5

Views: 17778

Answers (1)

Anatoliy Nikolaev
Anatoliy Nikolaev

Reputation: 22702

In your case it is better to use the Style for the Button, and use the Path instead of the Image. To properly implement the function of closing, it is better to implement it through a DependencyProperty and set the value directly in Style.

Example:

<Window x:Class="CloseButtonHelp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:CloseButtonHelp"
        Title="MainWindow" Height="350" Width="525">

<Window.Resources>
    <!-- Our style for the ToggleButton -->
    <Style x:Key="ToggleButtonWindowClose" TargetType="{x:Type ToggleButton}">
        <!-- Here you can set the initial properties for the control --> 
        <Setter Property="Background" Value="Transparent" />
        <Setter Property="SnapsToDevicePixels" Value="True" />

        <!-- Template needs to completely re-writing the standard control -->
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ToggleButton}">
                    <Grid>
                        <!-- Then responsible for the content. In our case it did not really need, because it is set Path -->
                        <ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" />      
                        <!-- Our Path. Shows a cross -->                       
                        <Path x:Name="CloseWindow" SnapsToDevicePixels="True" ToolTip="Close window" Width="18" Height="17" Margin="0,0,10,0" HorizontalAlignment="Right" VerticalAlignment="Center" Stretch="Fill" Fill="#2D2D2D" Data="F1 M 26.9166,22.1667L 37.9999,33.25L 49.0832,22.1668L 53.8332,26.9168L 42.7499,38L 53.8332,49.0834L 49.0833,53.8334L 37.9999,42.75L 26.9166,53.8334L 22.1666,49.0833L 33.25,38L 22.1667,26.9167L 26.9166,22.1667 Z " />
                    </Grid>

                    <!-- Trigger fires on the property --> 
                    <ControlTemplate.Triggers>
                        <!-- Here change the color when the mouse cursor -->
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="CloseWindow" Property="Fill" Value="#C10000" />
                        </Trigger>

                        <!-- Use ToggleButton, because it has a property IsChecked, accessible through the style -->
                        <Trigger Property="IsChecked" Value="True">
                            <Setter Property="local:WindowBehaviours.Close" Value="True" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

<Grid>
    <!-- Set the our style by key --->
    <ToggleButton Name="CloseButton" Style="{StaticResource ToggleButtonWindowClose}" />
</Grid>
</Window>

Listing of WindowBehaviorsClass:

public static class WindowBehaviours
{
    // Closing window
    public static void SetClose(DependencyObject target, bool value)
    {
        target.SetValue(CloseProperty, value);
    }

    public static readonly DependencyProperty CloseProperty =
                                              DependencyProperty.RegisterAttached("Close",
                                              typeof(bool),
                                              typeof(WindowBehaviours),
                                              new UIPropertyMetadata(false, OnClose));

    private static void OnClose(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        if (e.NewValue is bool && ((bool)e.NewValue))
        {
            Window window = GetWindow(sender);

            if (window != null)
            {
                window.Close();
            }
        }
    }

    private static Window GetWindow(DependencyObject sender)
    {
        Window window = null;

        if (sender is Window)
        {
            window = (Window)sender;
        }

        if (window == null)
        {
            window = Window.GetWindow(sender);
        }

        return window;
    }
}

For more information see MSDN.

Upvotes: 7

Related Questions