简体   繁体   中英

WPF find clicked button closest parent (TabItem) and close it

I am wondering whether there is a better simpler way rewrite the following code find the closest parent which is a TabItem and remove it from the TabControl.

I have a TabControl where I add new TabItems dynamically. I assign a HeaderTemplate to each tab which looks like this;

<DataTemplate x:Key="AttorneyTabHeader">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="THE title" Margin="2,0,0,0" FontSize="16" VerticalAlignment="Center" />
        <Button Width="Auto" UseLayoutRounding="False" BorderBrush="Transparent" Background="Transparent" Click="CloseAttorneysTabButtonClick">
            <Image Source="/images/close-cross-thin-circular-button/close-cross-thin-circular-button16.png" Height="16"></Image>
        </Button>
    </StackPanel>
</DataTemplate>

The header has a close button and I would like to close the TabItem whenever the button is clicked. My click handler looks like this;

public void CloseAttorneysTabButtonClick(object sender, RoutedEventArgs e)
{
    TabItem this_tab = (TabItem)((Button)sender).Parent.GetParentObject().GetParentObject().GetParentObject().GetParentObject().GetParentObject().GetParentObject();
    AttorneysTabControl.Items.Remove(this_tab);
}

I am wondering whether there is a better way to rewrite this because now I am depending on getting the parent over and over again suppose I change the button and forget changing the handler.

There's probably a few ways you can handle it, but the simplest is likely to bind to the TabItem in the Tag property for the Button so that you can use it in your event handler.

<DataTemplate x:Key="TabHeaderTemplate">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="The Title" Margin="2 0 0 0" FontSize="16" VerticalAlignment="Center" />
        <Button Width="Auto" UseLayoutRounding="False"
                BorderBrush="Transparent" Background="Transparent"
                Tag="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabItem}}, Mode=OneWay}"
                Click="Button_Click">
            <Image Source="images/close.png" Height="16" />
        </Button>
    </StackPanel>
</DataTemplate>

Now your event handler can be relatively simple, and doesn't need to know as much as it does in your example.

void Button_Click(object sender, RoutedEventArgs e)
{
    if (sender is Button button && button.Tag is TabItem item) {
        var tabControl = (TabControl)item.Parent;
        tabControl.Items.Remove(item);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM