根据选项卡的数量自动调整选项卡 headers (AvaloniaUI)
Automatically resize tab headers based on the count of tabs (AvaloniaUI)
我想像 chrome 一样在我的浏览器中实现 TabControl 的样式。选项卡的数量不固定,所以我希望选项卡 headers 根据选项卡的数量减少。
为此,我将 DataTemplate 中 Grid 的宽度绑定到选项卡的数量,然后传递给转换器,returns 实际宽度。
但由于某种原因这不起作用,我知道 TabItemCount 已准确传递给转换器。如果转换器 returns 为固定值,则不会阻止选项卡调整大小
风格:
<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-->
CountToWidthConverter:
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;
}
}
}
如果您需要更多代码,我一定会提供给您。
感谢考虑我的请求
我认为您可以使用 UniformGrid
作为面板模板,这样您就可以免费获得所有这些计算
<TabControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1" HorizontalAlignment="Left"/>
</ItemsPanelTemplate>
</TabControl.ItemsPanel>
然后您可能想要指定 TabItem
的 MinWidth
和 MaxWidth
并管理视图模型中的最大选项卡数。
我想像 chrome 一样在我的浏览器中实现 TabControl 的样式。选项卡的数量不固定,所以我希望选项卡 headers 根据选项卡的数量减少。
为此,我将 DataTemplate 中 Grid 的宽度绑定到选项卡的数量,然后传递给转换器,returns 实际宽度。
但由于某种原因这不起作用,我知道 TabItemCount 已准确传递给转换器。如果转换器 returns 为固定值,则不会阻止选项卡调整大小
风格:
<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-->
CountToWidthConverter:
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;
}
}
}
如果您需要更多代码,我一定会提供给您。 感谢考虑我的请求
我认为您可以使用 UniformGrid
作为面板模板,这样您就可以免费获得所有这些计算
<TabControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1" HorizontalAlignment="Left"/>
</ItemsPanelTemplate>
</TabControl.ItemsPanel>
然后您可能想要指定 TabItem
的 MinWidth
和 MaxWidth
并管理视图模型中的最大选项卡数。