Reputation: 23
In WindowsAPI, TabControl can calculate the (non-tab) client-area by AdjustRect command.
I want to calculate the (tabpage, not tabitem) tab control area in WPF.
How should I do?
XAML
MainWindow.xaml
...
<Grid>
<TabControl x:Name="tabcontrol"/>
<Button x:Name="outercontrol"/>
</Grid>
...
C#
MainWindow.xaml.cs
void Add(SomeObject obj)
{
TabItem item = new TabItem() { Header = obj.Text, Tag = obj };
tabcontrol.Items.Add(item);
RepositionControl();
}
void RepositionControl()
{
var margin = CalculateTabPageContentArea(); // like this...
this.outercontrol.Margin = margin;
}
Upvotes: 2
Views: 1994
Reputation: 44068
Ok. I see you're fundamentally wrong in almost everything you're thinking about WPF and how it works.
First of all, WPF is fundamentally different from any other technologies. If you're working with WPF, you really need to leave behind all the horrendous HACKS you might be used to from ancient technologies and embrace The WPF Mentality.
WPF UIs are composed of a Visual Tree where all visual elements are placed in a hierarchical manner. Therefore it can be said that all UI elements (except the top-most Window
) may have a Visual Parent and one or more Visual Children.
WPF also introduces the concept of ControlTemplates, which allows you to define the visual structure and appearance of any given Control without losing it's behavior and without resorting to horrible procedural practices such as "owner draw".
Given this, the WPF Layout System takes care of placing UI elements in their correct position "inside" their containing parent, taking into account several properties such as Template
, Margin
, VerticalAlignment
, HorizontalAlignment
, Width
and Height
.
Keep in mind that WPF is Resolution Independent, therefore most of the time you will NOT want to give a fixed size and position to UI elements, leaving the Layout System the freedom to adjust them to the available screen or parent Window size when the user resizes the Window.
Notice how this is a much better approach from the traditional, horrible winforms approach, where you would hard code all element sizes and therefore had to support only a specific window size.
Let's have a look at the Visual Tree of a TabControl
with 2 TabItem
s using the Default TabControl Template:
XAML:
<Window x:Class="MiscSamples.TabControlSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TabControlSample" Height="300" Width="300" x:Name="Window">
<TabControl>
<TabItem Header="Tab Item 1">
<TextBlock Text="Tab Content 1" x:Name="TabContent1"/>
</TabItem>
<TabItem Header="Tab Item 2">
<TextBlock Text="Tab Content 2" x:Name="TabContent2"/>
</TabItem>
</TabControl>
</Window>
Result:
Using Snoop or a similar spy tool, we can see the following Visual Tree generated by the above XAML:
First thing you notice here is that there is a LOT more going on than just TabItem
s and TextBlock
s, which is what we defined in XAML. That's because of the ControlTemplates, which define the internal Visual Tree of any given Control.
This is the main reason for which you're not supposed to bother WPF with any procedural hacks, and instead let it do it's work, which it does pretty well.
I suggest you start by reading the above linked "WPF Mentality" post and this introduction to WPF layouts.
Let me know if you need further help.
Upvotes: 2