根据选项卡的数量自动调整选项卡标题的大小 (AvaloniaUI)

Posted

技术标签:

【中文标题】根据选项卡的数量自动调整选项卡标题的大小 (AvaloniaUI)【英文标题】:Automatically resize tab headers based on the count of tabs (AvaloniaUI) 【发布时间】:2022-01-04 08:27:18 【问题描述】:

我想在我的浏览器中实现 TabControl 的样式,就像在 chrome 中一样。选项卡的数量不固定,所以我希望选项卡标题根据选项卡的数量减少。

为此,我将 DataTemplate 中 Grid 的宽度绑定到选项卡的数量,该数量被传递给转换器,该转换器返回实际宽度。

但由于某种原因这不起作用,我知道 TabItemCount 已准确传递给转换器。如果转换器返回一个固定值,那么没有什么能阻止标签调整大小

风格:

<Style Selector="TabControl">
        <Setter Property="BorderThickness" Value="0"></Setter>
        <Setter Property="ItemsPanel">
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal" 
                            Height="50"
                            Margin="10,-5,-10,5"></StackPanel>
            </ItemsPanelTemplate>
        </Setter>
        <Setter Property="ContentTemplate">
            <DataTemplate DataType="vm:WebsiteTabVM">
                <views:WebsiteTab></views:WebsiteTab>
            </DataTemplate>
        </Setter>
        <Setter Property="ItemTemplate">
            <DataTemplate DataType="vm:TabVM">
                <Grid Width="Binding DataContext.TabItemCount, 
                             Converter=StaticResource CountToWidthConverter,
                             RelativeSource=RelativeSource FindAncestor, AncestorType=x:Type TabControl"
                      HorizontalAlignment="Center" VerticalAlignment="Center"
                      Margin="5">

                      <!--ItemTemplate-->

CountToWidth转换器:

using Avalonia.Data.Converters;
using System;

namespace SimpleBrowser.Helpers

    public class CountToWidthConverter : IValueConverter
    
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        
            return 1000 / (int)value;
        

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        
            throw new NotImplementedException();
        
    

MainVM,它有一个计数选项卡属性:

using Avalonia.Controls;
using Microsoft.Toolkit.Mvvm.Input;
using ReactiveUI;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Input;
using System.Linq;

namespace SimpleBrowser.ViewModels

    public class MainVM : ViewModelBase
    
        public MainVM()
        
            TabVMs = new ObservableCollection<TabVM>();
            TabVMs.Add(new WebsiteTabVM());
            TabVMs.Add(new WebsiteTabVM() Name="Test tab withbigtext");
            TabVMs.Add(new WebsiteTabVM());
            TabVMs.Add(new WebsiteTabVM());

            SortTabs();
        
        private ObservableCollection<TabVM> _tabVMs;
        public ObservableCollection<TabVM> TabVMs
        
            get  return _tabVMs; 
            set 
             
                this.RaiseAndSetIfChanged(ref _tabVMs, value);
                TabItemCount = TabVMs.Count;
            
        

        private double _tabItemCount;
        public double TabItemCount
        
            get  return _tabItemCount; 
            set  this.RaiseAndSetIfChanged(ref _tabItemCount, value); 
        

        #region Command
        private ICommand _addNewTab;
        public ICommand AddNewTab
        
            get
            
                return _addNewTab ??= new RelayCommand(() =>
                
                    TabVMs.Add(new WebsiteTabVM());
                    SortTabs();
                );
            
        
        private ICommand _removeTab;
        public ICommand RemoveTab
        
            get
            
                return _removeTab ??= new RelayCommand<int>(obj =>
                
                    TabVMs.RemoveAt(obj);
                    SortTabs();
                );
            
        
        #endregion

        public void SortTabs()
        
            for (int i = 0; i < TabVMs.Count; i++)
            
                TabVMs[i].Index = i;
                TabVMs[i].IsTabLast = false;
            
            TabVMs.Last().IsTabLast = true;
            TabItemCount = TabVMs.Count;
        
    

如果您需要更多代码,我一定会为您提供。 感谢您考虑我的要求

【问题讨论】:

【参考方案1】:

我认为您可以将UniformGrid 用作面板模板,这样您就可以免费获得所有这些计算

<TabControl.ItemsPanel>
    <ItemsPanelTemplate>
        <UniformGrid Rows="1" HorizontalAlignment="Left"/>
    </ItemsPanelTemplate>
</TabControl.ItemsPanel>

那么您可能想要指定TabItem 中的MinWidthMaxWidth 并管理视图模型中的最大选项卡数。

【讨论】:

非常感谢!这正是我所需要的

以上是关于根据选项卡的数量自动调整选项卡标题的大小 (AvaloniaUI)的主要内容,如果未能解决你的问题,请参考以下文章

使每个选项卡的大小相同且可展开[关闭]

当添加子选项卡时,如何使 qtabwidget 实例自动调整大小?

CSS选项卡宽度自动调整大小

在 flex3 中调整 TabNavigator 中的内容大小

更改 Android 中活动或非活动选项卡的文本大小

Excel表怎么让单元格自动调整宽度?