C# 使TabControl宽度等于最大TabItems宽度和高度
我有一个C# 使TabControl宽度等于最大TabItems宽度和高度,c#,wpf,tabcontrol,C#,Wpf,Tabcontrol,我有一个TabControl,里面有许多TabItems。 我试图使TabControl的宽度等于其TabItems宽度的最大值(高度相同)。 我无法显式设置它,因为我的程序是多语言的,因此根据所选语言的不同,我需要为所有标签设置不同的宽度(它们都处于“自动”状态) 有没有办法只在XAML中使用 编辑: 我在代码中找到了解决方案的一部分:当我打开窗口时,我执行以下操作: List<TabItem> list = new List<TabItem>(); list.AddR
TabControl
,里面有许多TabItems
。
我试图使TabControl的宽度
等于其TabItems宽度的最大值
(高度相同)。
我无法显式设置它,因为我的程序是多语言的,因此根据所选语言的不同,我需要为所有标签设置不同的宽度(它们都处于“自动”状态)
有没有办法只在XAML中使用
编辑:
我在代码中找到了解决方案的一部分:当我打开窗口时,我执行以下操作:
List<TabItem> list = new List<TabItem>();
list.AddRange(tabControl.Items.OfType<TabItem>());
foreach (TabItem tabItem in list)
{
tabControl.SelectedItem=tabItem;
tabControl.UpdateLayout();
tabItem.UpdateLayout();
System.Threading.Thread.Sleep(250);
maxWidth = Math.Max(maxWidth, tabItem.ActualWidth);
maxHeight = Math.Max(maxHeight, tabItem.ActualHeight);
}
tabControl.Width = maxWidth;
tabControl.Height = maxHeight;
private void TabControlSizeChanged(object sender, SizeChangedEventArgs e)
{
if(this.allTabItemsChecked==false)
{
int index = tabControl.SelectedIndex;
List<TabItem> list = new List<TabItem>();
list.AddRange(tabControl.Items.OfType<TabItem>());
if (index < list.Count()-1)
{
tabControl.SelectedIndex = index + 1;
}
else
{
this.allTabItemsChecked = true;
tabControl.SelectedIndex = 0;
}
contexte.TabControlWidth = Math.Max(tabControl.ActualWidth, contexte.TabControlWidth);
contexte.TabControlHeight = Math.Max(tabControl.ActualHeight, contexte.TabControlHeight);
}
}
List List=新列表();
list.AddRange(tabControl.Items.OfType());
foreach(列表中的TabItem TabItem)
{
tabControl.SelectedItem=tabItem;
tabControl.UpdateLayout();
tabItem.UpdateLayout();
系统线程线程睡眠(250);
maxWidth=Math.Max(maxWidth,tabItem.ActualWidth);
maxHeight=Math.Max(maxHeight,tabItem.ActualHeight);
}
tabControl.Width=maxWidth;
tabControl.Height=maxHeight;
这似乎是一个有效的解决方案,但我不明白为什么tabItem.ActualWidth
和tabItem.ActualHeight
总是设置为0
为了更好地理解,我放了一个窗口截图:
当我打开窗口时,我已经知道可以用哪种语言打开它,因此在加载窗口后,选项卡项维度不会改变
编辑2:
以下是我所说的“TabItems的大小因使用的语言而异”的具体含义,这不是最好的例子,因为这里的差异很小,但我想将其应用到我项目的所有TabControl中,以确保如果我将来进行更改,甚至添加其他语言,我永远不会遇到问题:
俄语:
英文:
我终于找到了一个解决方案,也许不是最好的,但它工作得很好,没有找到任何其他解决方案。 初始化窗口时无法执行此操作,因为内容尚未加载(MyWindow.Show()),因此我必须使用TabControl的SizeChanged事件 在我的ViewModel上,我设置了两个参数
TabControlWidth
和TabControlHeight
private double tabControlWidth = 0;
public double TabControlWidth
{
get { return tabControlWidth; }
set
{
if (this.tabControlWidth != value)
{
tabControlWidth = value;
this.NotifyPropertyChanged("TabControlWidth");
}
}
}
private double tabControlHeight = 0;
public double TabControlHeight
{
get { return tabControlHeight; }
set
{
if (this.tabControlHeight != value)
{
tabControlHeight = value;
this.NotifyPropertyChanged("TabControlHeight");
}
}
}
在我的文件MyWindow.xaml.cs中,我添加了一个bool属性,以便在检查所有TabItems时进行检查(显然,初始化窗口时该属性设置为false):
最后,我需要在TabControl中添加两件事:
- 将宽度和高度绑定到ViewModel中的“我的属性”
- 添加事件大小更改 SizeChanged=“TabControlSizeChanged”MinHeight=“{Binding TabControlHeight}”MinWidth=“{Binding TabControlWidth}”
List<TabItem> list = new List<TabItem>();
list.AddRange(tabControl.Items.OfType<TabItem>());
foreach (TabItem tabItem in list)
{
tabControl.SelectedItem=tabItem;
tabControl.UpdateLayout();
tabItem.UpdateLayout();
System.Threading.Thread.Sleep(250);
maxWidth = Math.Max(maxWidth, tabItem.ActualWidth);
maxHeight = Math.Max(maxHeight, tabItem.ActualHeight);
}
tabControl.Width = maxWidth;
tabControl.Height = maxHeight;
private void TabControlSizeChanged(object sender, SizeChangedEventArgs e)
{
if(this.allTabItemsChecked==false)
{
int index = tabControl.SelectedIndex;
List<TabItem> list = new List<TabItem>();
list.AddRange(tabControl.Items.OfType<TabItem>());
if (index < list.Count()-1)
{
tabControl.SelectedIndex = index + 1;
}
else
{
this.allTabItemsChecked = true;
tabControl.SelectedIndex = 0;
}
contexte.TabControlWidth = Math.Max(tabControl.ActualWidth, contexte.TabControlWidth);
contexte.TabControlHeight = Math.Max(tabControl.ActualHeight, contexte.TabControlHeight);
}
}
private void选项卡ControlSizeChanged(对象发送方,SizeChangedEventArgs e)
{
if(this.allTabItemsChecked==false)
{
int index=tabControl.SelectedIndex;
列表=新列表();
list.AddRange(tabControl.Items.OfType());
如果(索引
当我们显示窗口时,事件将自动启动。
然后将TabControl.SelectedIndex更改为下一个TabItem,并将TabControl维度更新为更大的维度。
当我到达最后一个索引时,我只是将SelectedIndex设置为0,然后将allTabItemsChecked设置为true。新的选项卡项多久出现一次,它们的宽度多久改变一次?一个更传统的解决方案是给选项卡控件提供所有您可以使用的空间,并设计选项卡项布局以调整到可用的空间。我有5个选项卡项,它们的当窗口打开时,尺寸不会改变,但它们的尺寸可能会因软件使用的语言而异。具体地说,当我打开菜单“选项”时,这会打开一个新的WPF窗口,其中有一个TabControl,每个TabItem对应于选项的某些部分(对于现在的常规、嵌套、标记、钻孔、时间管理)@EdPlunkett我想我找到了一个合适的解决方案(见我的编辑),如果你有想法的话,谢谢。我想你必须迭代你的项目,将它们呈现在屏幕外,并检查所需的大小。然后将当前项目的宽度设置为该宽度。这就是为什么“通常“方法是使tabcontrol足够大,可以容纳任何项目,并使项目具有“额外”宽度。并将其内容包装在scrollviewer中,这样它们就永远不会被切断。@Andy“将其渲染到屏幕外”是什么意思?”?这大概是我玩的东西。它不漂亮,但如果它能工作,它就会工作。我认为这是你能找到的最健壮的选项,除了使用你所有的空间。我个人更喜欢将其排除在viewmodel之外。我更喜欢编写两个附加的依赖属性,并将它们放在TabControl本身上,然后用ith
{RelativeSource AncestorType=Window}
。我还将这两个属性绑定到MinHeight和MinWidth,以防某个选项卡项中的布局可能会在某个角落扩展,而我忘记了测试,因为某些内容是自动调整大小的。@EdPlunkett为什么不在ViewModel中?可能是我的一个坏习惯,但通常只有我的ViewModelINotifyPropertyChanged
,如果我将我的属性在我的窗口中,为了更新绑定,我没有选择使我的窗口INotifyPropertyChanged
?不,使它们成为依赖属性。依赖属性有自己的通知机制。永远不要在窗口或控件中实现INPC。我会将其排除在viewmodel之外,因为这是控件的状态。如果