Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使TabControl宽度等于最大TabItems宽度和高度_C#_Wpf_Tabcontrol - Fatal编程技术网

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}”

(对不起,我无法将最后一行显示为代码?通常发生在我使用“-”或“*”)之后)

最后,我制作了SizeChanged函数,如下所示:

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中?可能是我的一个坏习惯,但通常只有我的ViewModel
INotifyPropertyChanged
,如果我将我的属性在我的窗口中,为了更新绑定,我没有选择使我的窗口
INotifyPropertyChanged
?不,使它们成为依赖属性。依赖属性有自己的通知机制。永远不要在窗口或控件中实现INPC。我会将其排除在viewmodel之外,因为这是控件的状态。如果