Effect:
Although it is adaptive can be closed TabControl, but TabControl do not need to change, rather called adaptive can be closed tabitem.
General idea: Build a user control, inherit from TabItem, inside Put a button, click the time in the TabControl to remove itself. When adding, removing TabItem and TabControl dimension changes, the appropriate width is calculated by the number of items.
New User Control
Creates a new user control and inherits from TabItem so that it has all the properties and events of TabItem. This feature does not require custom dependency properties and events. It is used exactly like TabItem.
After the construction, replace the UserControl with TabItem and remove the superfluous parts.
Background inheritance from UserControl to inherit from TabItem
Change Style Add Close button
Add a favorite style to the Xmal, the main thing is to add a button in the template, register a click event, to close.
1 <style targettype= "{x:type TabItem}" > 2 <setter property= "BorderBrush" value= "Black" ></sette R> 3 <setter property= "Background" value= "White" ></Setter> 4 <setter property= "F Oreground "value=" Black "></Setter> 5 <setter property=" Padding "value=" 5,0,0,0 "></Setter> 6 <setter property= "HorizontalAlignment" value= "left" ></Setter> 7 <setter Property = "VerticalAlignment" value= "Center" ></Setter> 8 <setter property= "Horizontalcontentalignment" Valu E= "left" ></Setter> 9 <setter property= "verticalcontentalignment" value= "Center" ></Setter> Ten <setter property= "Template" >11 <setter.value>12 <control Template targettype= "{x:type TabItem}" >13 <border cornerradius= "5,0,0,0" borderbrush= "{Templ Atebinding BorderBrush} " borderthickness= "{TemplateBinding borderthickness}" background= "{TemplateBinding Background}" >14 <grid>15 <grid.columndefinitions>16 <columndefinition width= "*" ></columndefinition>17 <columndefinition Wi Dth= "></columndefinition>18 </grid.columndefinitions>19" <contentpresenter grid.column= "0" contentsource= "Header" margin= "{TemplateBinding Padding}" Horizontala Lignment= "{TemplateBinding horizontalcontentalignment}" verticalalignment= "{TemplateBinding Verticalcontentalignment} "></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 & Lt Setter property= "Foreground" value= "white" ></setter>27 </trigger>28 </controltemplate.triggers>29 </controltemplate>30 </sette R.value>31 </setter>32 </Style>
Logical lookup of the background parent TabControl
Note that TabItem does not close itself, The closure in this case is actually removed from the items collection of his parent TabControl. And when the size of the parent TabControl changes, register the event to change the width of each item. So I decided to find its parent TabControl, Declares a private variable to add a reference to the parent.
It is possible to find its parent TabControl through the Help class visualtreehelper of the visual tree. Of course, it's not the parent. It's just TabControl.
1//<summary> 2// recursion for parent TabControl 3// </summary> 4// <param name= "Reference" > Dependent objects </param> 5 //<returns>TabControl</returns> 6 private TabControl Findparenttabcontrol ( DependencyObject Reference) 7 {8 DependencyObject dobj = visualtreehelper.getparent (reference); 9 if ( Dobj = = null) return null;11 if (dobj.gettype () = = typeof (TabControl)) return dobj as tabcontrol;13< C11/>else14 return Findparenttabcontrol (dobj);
Calculate dimensions
Since it is adaptive, there must be a normal size, only when the space is not enough to narrow down each item. The simplest way I can think of is to make a pact to put this dimension in the parent TabControl tag, so that by referring to the parent TabControl, Easily get this size.
The calculation method is to take the parent TabControl runtime width ActualWidth divided by the agreed size, take the shaping int, this is to keep the agreed width of the item number of the critical value.
This value is less than or equal to the agreed width, which is greater than the value of the parent run width divided by the number of items to find the average width, and then traverse the parent TabControl items, all assigned this mean.
It is important to note that if all items have a size that is greater than or equal to the parent's size, items will wrap and feel a bit ugly. So I took the operation of the parent run width-5, so that never arrives at the boundary, and does not break the line.
But can also rewrite TabControl control template, put Hrader container replaced StackPanel will not change line, I just think the above method is relatively simple.
Parent size Change
can be monitored through the TabControl sizechanged event. The thing to do is to recalculate the dimensions.
Close button
After removing itself from the items collection in the parent TabControl, be careful to recalculate the size and remove the method of registering the SizeChanged event.
Finally, attach the Code Adaptive tab that can be closed
This effect is more common, you may have already done, have a better idea hope you can share it, we progress together
WPF adaptive can close TabControl browser-like tabs (GO)