C# 如何获取TabControl WPF的TabItem的标题宽度
我需要做的是停止GridSplitter,然后再进一步隐藏TabControl。因此,我想到的想法是将所有TabItems标题的实际宽度之和绑定到TabControl的MinWidth或保留TabControl的Crid单元格。但问题是到目前为止我无法访问TabItem的标题宽度。我找到的一个解决方案是在Tabitem.Header中放置一个TextBlock,声明其宽度并用x:name命名。但是用这种方式使用宽度并不能给出页眉的总宽度,包括边距和填充物等,因此它甚至不能接近准确度 更新 这是密码。请注意,我已经实现了其中一个解决方案,但如果动态加载选项卡,它不会控制MinWidthC# 如何获取TabControl WPF的TabItem的标题宽度,c#,wpf,tabitem,actualwidth,C#,Wpf,Tabitem,Actualwidth,我需要做的是停止GridSplitter,然后再进一步隐藏TabControl。因此,我想到的想法是将所有TabItems标题的实际宽度之和绑定到TabControl的MinWidth或保留TabControl的Crid单元格。但问题是到目前为止我无法访问TabItem的标题宽度。我找到的一个解决方案是在Tabitem.Header中放置一个TextBlock,声明其宽度并用x:name命名。但是用这种方式使用宽度并不能给出页眉的总宽度,包括边距和填充物等,因此它甚至不能接近准确度 更新 这是密
<Grid Background="#FFD6DBE9" Height="614" Width="1109">
<Grid.RowDefinitions>
<RowDefinition Height="89"/>
<RowDefinition Height="Auto" MinHeight="{Binding ActualHeight, ElementName=gridNotificationsHeader}"/>
<RowDefinition Height="494*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="400*" MinWidth="{Binding MinWidth, ElementName=tabDataEntities}"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="144*">
<ColumnDefinition.MinWidth>
<MultiBinding Converter="{StaticResource StringSumtoIntConvert}">
<Binding ElementName="cdLblNotificationsHeader" Path="MinWidth"/>
<Binding ElementName="cdBtnNotificationsClose" Path="ActualWidth"/>
</MultiBinding>
</ColumnDefinition.MinWidth>
</ColumnDefinition>
</Grid.ColumnDefinitions>
<GridSplitter x:Name="gridSplitter" Grid.Column="1" HorizontalAlignment="Center" Grid.Row="1" Width="2" Grid.RowSpan="2"/>
<Grid x:Name="gridNotificationsHeader" Grid.Column="2" Background="#FF657695"
Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="cdLblNotificationsHeader" MinWidth="{Binding Width, ElementName=lblNotificationsHeader}"/>
<ColumnDefinition x:Name="cdBtnNotificationsClose" Width="Auto"/>
</Grid.ColumnDefinitions>
<Label x:Name="lblNotificationsHeader" Content="Notifications" VerticalAlignment="Top"
FontSize="14.667" Height="30" Foreground="#FFEBF0EE" HorizontalAlignment="Left" Width="92"/>
<Button x:Name="btnNotificationsClose" Content="X"
Margin="0,5,8,0" VerticalAlignment="Top" Width="20" FontFamily="Verdana" HorizontalAlignment="Right" Background="Transparent" FontSize="13.333" Foreground="Black" Grid.Column="1"/>
</Grid>
<TabControl x:Name="tabDataEntities" Margin="0,0,5,10" Grid.Row="1" Grid.RowSpan="2" FontSize="12" Grid.ColumnSpan="1" MinWidth="{Binding ElementName=TabItemOne, Path=ActualWidth}">
<TabItem x:Name="TabItemOne">
<TabItem.Header>Tab Item</TabItem.Header>
<Grid Background="#FFE5E5E5"/>
</TabItem>
<TabItem Header="TabItem">
<Grid Background="#FFE5E5E5"/>
</TabItem>
</TabControl>
</Grid>
选项卡项
就这么简单
<StackPanel>
<TabControl>
<TabItem Header="Hello world" Name="Tab1"/>
<TabItem Header="Hello" Name="Tab2"/>
<TabItem Header="world" Name="Tab3"/>
</TabControl>
<TextBlock Text="{Binding ElementName=Tab1, Path=ActualWidth}"/>
<TextBlock Text="{Binding ElementName=Tab2, Path=ActualWidth}"/>
<TextBlock Text="{Binding ElementName=Tab3, Path=ActualWidth}"/>
</StackPanel>
刚刚做了以下
附件属性时有点开心
:
XAML使用情况
<TabControl question32926699:TabControlHeaderWidthWatcher.WatchHeadersWidth="true"
question32926699:TabControlHeaderWidthWatcher.TotalHeadersWidth="{Binding TotalWidth, Mode=OneWayToSource}">
<TabItem Header="Tab Item 1" />
<TabItem Header="Tab Item 2" />
</TabControl>
即使您使用
TabControl
的ItemsSource
动态加载选项卡,此解决方案也会起作用。TotalHeadersWidth
将始终接收总页眉宽度,除非选项卡被包装成多行。在这种情况下,它将使用TabControl
本身的ActualWidth
,在您的情况下,它提供了我们想要的。您可以添加您编写的XAML吗?Konstantin Brownstein的答案有效。感谢您的回复@KOTIXKonstantin的回答很好。但是,这种解决方案只有在选项卡项是固定的而不是动态加载的情况下才有效。拥有XAML源代码将有助于定义用例。我仍然对通过动态加载选项卡来实现您的要求感兴趣。我添加了XAML,您可以查看。谢谢。我不知道为什么我不先尝试一下太简单的事情。@FawadKhalil没问题,如果你想实现MVVM,只需将ActualWidth绑定到某个属性并使用它,它就可以像well@KonstantinBrownstein使用Tabcontrol(动态生成的选项卡)上的ItemSource如何工作?
public class TabControlHeaderWidthWatcher
{
private static TabControl m_tabControl;
public static readonly DependencyProperty WatchHeadersWidthProperty = DependencyProperty.RegisterAttached(
"WatchHeadersWidth", typeof (bool), typeof (TabControlHeaderWidthWatcher), new PropertyMetadata(default(bool), PropertyChangedCallback));
public static void SetWatchHeadersWidth(DependencyObject element, bool value)
{
element.SetValue(WatchHeadersWidthProperty, value);
}
public static bool GetWatchHeadersWidth(DependencyObject element)
{
return (bool)element.GetValue(WatchHeadersWidthProperty);
}
public static readonly DependencyProperty TotalHeadersWidthProperty = DependencyProperty.RegisterAttached(
"TotalHeadersWidth", typeof (double), typeof (TabControlHeaderWidthWatcher), new PropertyMetadata(default(double)));
public static void SetTotalHeadersWidth(DependencyObject element, double value)
{
element.SetValue(TotalHeadersWidthProperty, value);
}
public static double GetTotalHeadersWidth(DependencyObject element)
{
return (double) element.GetValue(TotalHeadersWidthProperty);
}
private static void PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
m_tabControl = dependencyObject as TabControl;
if (m_tabControl == null) return;
((INotifyCollectionChanged)m_tabControl.Items).CollectionChanged += CollectionChanged;
}
private static void CollectionChanged(object sender, EventArgs eventArgs)
{
foreach (var item in m_tabControl.Items)
{
var tabItem = item as TabItem;
if (tabItem == null) continue;
// Unsubscribe first in case it was there previously
tabItem.SizeChanged -= TabItemOnSizeChanged;
tabItem.SizeChanged += TabItemOnSizeChanged;
}
}
private static void TabItemOnSizeChanged(object sender, SizeChangedEventArgs sizeChangedEventArgs)
{
var totalWidth = 0.0;
foreach (var item in m_tabControl.Items)
{
var tabItem = item as TabItem;
if (tabItem == null) continue;
totalWidth += tabItem.ActualWidth;
}
// When more than one row of tabs, the width of the TabControl is used
var actualWidth = totalWidth > m_tabControl.ActualWidth ? m_tabControl.ActualWidth : totalWidth;
SetTotalHeadersWidth(m_tabControl, actualWidth);
}
}