Sándor Tamás
Sándor Tamás

Reputation: 193

Button.Click in Custom control

I want to create a new custom control derived from ContentControl (it will be a container for other controls in a window), but I want a button to close it. (in fact I want a borderless window, but with system-like button to close it).

So I created the Style for the control which contains a Grid with two rows, in the upper row there's a StackPanel with a single button.

How can I bind the Click event of the button to the control itself, to raise an event, or even to send Close command to the parent window?

<Grid>
<Grid.RowDefinitions>
    <RowDefinition Height="20" />
    <RowDefinition />
</Grid.RowDefinitions>
<Border Background="Azure" Grid.Row="0">
    <StackPanel Orientation="Horizontal">
        <Button HorizontalAlignment="Right" Content="X" Click="Close_Click" />
    </StackPanel>
    </Border>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="1"/>
</Grid>

And the code behind:

static STContentControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(STContentControl), new FrameworkPropertyMetadata(typeof(STContentControl)));
}

public void Close_Click(object sender, RoutedEventArgs ea)
{

}

Upvotes: 3

Views: 1978

Answers (1)

Charleh
Charleh

Reputation: 14002

It sounds like you have created the template as a resource so it's being applied to the control at runtime.

You need to make sure you wire up your click event for the button in the OnApplyTemplate method (override this on your control).

http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.onapplytemplate.aspx

So you would override this on your UC like so:

class NewUC : UserControl
{
    public event EventHandler CloseClicked;

    public override void OnApplyTemplate()
    {
        Button btn = this.FindName("SomeButton") as Button;

        if (btn == null) throw new Exception("Couldn't find 'Button'");

        btn.Click += new System.Windows.RoutedEventHandler(btn_Click);
    }

    void btn_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        OnCloseClicked();
    }

    private void OnCloseClicked()
    {
        if (CloseClicked != null)
            CloseClicked(this, EventArgs.Empty);
    }
}    

I added a CloseClicked event to the example which you could handle in your parent window. This isn't a routed event so you would have to manually wire it up in the parent control

Methinks you could also use MouseLeftButtonDown routed event and check to see if the button was clicked at the parent level - will have a go myself...

Upvotes: 3

Related Questions