The self-adaptive and closed TabControl of WPF is similar to the tab of the browser, wpftabcontrol

Source: Internet
Author: User

The self-adaptive and closed TabControl of WPF is similar to the tab of the browser, wpftabcontrol

Effect:

Although it is an adaptive and closed TabControl, TabControl does not need to be changed. Instead, it is called an adaptive and closed TabItem.

General idea: create a user control that inherits from TabItem. Put a button in it and remove itself from TabControl when you click it. when you add or remove the size changes of TabItem and TabControl, use the number of Items to calculate the appropriate Width.

Create a user control

Create a user control and inherit from TabItem, so that it has all the attributes and events of TabItem. this feature does not require custom dependency attributes and events. its usage is exactly the same as that of TabItem.

After creation, replace UserControl with TabItem to remove unnecessary parts.

Changed from UserControl inherited from TabItem in the background

Change style add close button

Add a style you like in Xmal. The most important thing is to add a button in the Template and register a Click event for closing.

1 <Style TargetType = "{x: type TabItem} "> 2 <Setter Property =" BorderBrush "Value =" Black "> </Setter> 3 <Setter Property =" Background "Value =" White "> </Setter> 4 <Setter Property = "Foreground" Value = "Black"> </Setter> 5 <Setter Property = "Padding" Value = "5, 0, 0, 0 "> </Setter> 6 <Setter Property =" HorizontalAlignment "Value =" Left "> </Setter> 7 <Setter Property =" verticalignment "Value =" Center "> </Setter> 8 <Setter Property = "HorizontalContentAlignment" Value = "Left"> </Setter> 9 <Setter Property = "VerticalContentAlignment" Value = "Center"> </Setter> 10 <Setter Property = "Template"> 11 <Setter. value> 12 <ControlTemplate TargetType = "{x: Type TabItem}"> 13 <Border CornerRadius = "5, 0, 0, 0 "BorderBrush =" {TemplateBinding BorderBrush} "BorderThickness =" {TemplateBinding BorderThickness} "Background =" {TemplateBinding Background} "> 14 <Grid> 15 <Grid. columnDefinitions> 16 <ColumnDefinition Width = "*"> </ColumnDefinition> 17 <ColumnDefinition Width = "20"> </ColumnDefinition> 18 </Grid. columnDefinitions> 19 <ContentPresenter Grid. column = "0" ContentSource = "Header" Margin = "{TemplateBinding Padding}" encoding = "{TemplateBinding encoding}" verticalignment = "{TemplateBinding encoding}"> </ContentPresenter> 20 <Button Grid. column = "1" Name = "btn_Close" Click = "btn_Close_Click"> </Button> 21 </Grid> 22 </Border> 23 <ControlTemplate. triggers> 24 <Trigger Property = "IsSelected" Value = "true"> 25 <Setter Property = "Background" Value = "# FFFF923E"> </Setter> 26 <Setter Property = "Foreground" Value = "White"> </Setter> 27 </Trigger> 28 </ControlTemplate. triggers> 29 </ControlTemplate> 30 </Setter. value> 31 </Setter> 32 </Style>View Code

 

Logical search for the parent TabControl in the background

Note that TabItem cannot close itself. The closure mentioned here is actually removed from the Items set of its parent TabControl. when the size of the parent TabControl changes, you must register an event to change the Width of each Item. so I decided to find its parent TabControl and declare a private variable to add a reference to the parent.

You can use the visual tree help class VisualTreeHelper to find its parent TabControl. Of course, it is not its parent level, but it is TabControl. You Need To Recursively search for it.

1 // <summary> 2 // recursively find the parent TabControl 3 // </summary> 4 // <param name = "reference"> dependent object </ param> 5 // <returns> TabControl </returns> 6 private TabControl FindParentTabControl (DependencyObject reference) 7 {8 DependencyObject dObj = VisualTreeHelper. getParent (reference); 9 if (dObj = null) 10 return null; 11 if (dObj. getType () = typeof (TabControl) 12 return dObj as TabControl; 13 else14 return FindParentTabControl (dObj); 15}View Code

 

Computing size

Since it is adaptive, there must be a normal size, and each Item can be reduced only when space is insufficient. the simplest way to think of it is to make an agreement to put the size in the Tag of the parent TabControl, so that you can easily get the size by referencing the parent TabControl.

The calculation method is to take the width of the parent TabControl runtime ActualWidth divided by the agreed size, and take the integer int, which is the critical value to keep the number of items of the agreed width.

If the value is less than or equal to this value, the agreed width is used. If the value is greater than this value, the average width is obtained by dividing the parent running width by the number of Items, and then the Items of the parent TabControl is traversed, and the average value is assigned.

It should be noted that if the size of all Items is greater than or equal to the size of the parent, Items will wrap the line and it feels a little ugly. therefore, I took the calculation of the parent-level running width-5, so that it will never reach the boundary and will not wrap.

However, you can also rewrite the TabControl control template and replace the container with Stackpanel to avoid line breaks. I just think the above method is relatively simple.

Parent dimension change

We can monitor the SizeChanged event of TabControl. The task is to re-calculate the size.

Close button

After removing itself from the Items set of the parent TabControl, you must recalculate the size and remove the method for registering the SizeChanged event.

The Code adaptive and closed Tab is attached.

This effect is quite common. You may have already done it. I hope you can share it with us and make progress together.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.