我用ComboBox
将所有字体加载到计算机上并进行预览。
这是XAML:
<Window x:Class="Sample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Sample"
mc:Ignorable="d"
Title="Demo" Height="450" Width="800" WindowStartupLocation="CenterScreen" WindowStyle="None" Loaded="Window_Loaded" Background="White">
<Window.Resources>
<local:FontFamilyConverter x:Key="FontFamilyConverter"></local:FontFamilyConverter>
</Window.Resources>
<Grid>
<ComboBox Margin="10,10,0,10" HorizontalContentAlignment="Stretch" Name="FontFaimlyCB" Height="50" Width="250" ItemsSource="{Binding Source={x:Static Fonts.SystemFontFamilies}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" FontFamily="{Binding Converter={StaticResource FontFamilyConverter}}" FontSize="20"></TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
</Window>
这是代码背后:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Threading;
using System.Globalization;
namespace Sample
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
}
}
public class FontFamilyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return new FontFamily(value.ToString());
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
当我第一次单击ComboBox
时,总是需要很长时间才能添加项目(我的计算机上几乎有1000种字体,完成它需要3-4秒)。但是其他任何软件(例如word / photoshop等)都不会这样。
如何使其添加速度更快?请帮助我,谢谢。
答案 0 :(得分:2)
您可以尝试将VirtualizingStackPanel
用作ItemsPanel
,并将MaxDropDownHeight
设置为一个很小的值,以便不立即呈现所有容器。而且您不必使用转换器:
<ComboBox Margin="10,10,0,10" HorizontalContentAlignment="Stretch" Name="FontFaimlyCB" Height="50" Width="250"
ItemsSource="{Binding Source={x:Static Fonts.SystemFontFamilies}}"
MaxDropDownHeight="50">
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" FontFamily="{Binding}" FontSize="20" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
答案 1 :(得分:0)
创建自己的可观察集合,使您可以在添加项目时挂起通知。例如:
static void Main(string[] args)
{
var fonts = new ObservableCollectionEx<string>();
using (fonts.DeferCollectionChanged())
{
for (int i = 0; i < 100000; i++)
{
fonts.Add(Guid.NewGuid().ToString());
}
}
}
public class ObservableCollectionEx<T> : ObservableCollection<T>
{
private int deferLevel;
private bool collectionUpdateNeeded;
public ObservableCollectionEx()
{
}
public ObservableCollectionEx(IEnumerable<T> collection)
: base(collection)
{
}
public ObservableCollectionEx(List<T> collection)
: base(collection)
{
}
public override event NotifyCollectionChangedEventHandler CollectionChanged;
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (deferLevel == 0)
{
CollectionChanged?.Invoke(this, e);
collectionUpdateNeeded = false;
}
else
{
collectionUpdateNeeded = true;
}
}
public IDisposable DeferCollectionChanged()
{
++deferLevel;
return new DeferHelper(this);
}
private void EndDefer()
{
--deferLevel;
if (deferLevel == 0 && collectionUpdateNeeded)
{
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}
private class DeferHelper : IDisposable
{
private ObservableCollectionEx<T> collection;
public DeferHelper(ObservableCollectionEx<T> collection)
{
this.collection = collection;
}
public void Dispose()
{
if (collection != null)
{
collection.EndDefer();
collection = null;
}
}
}
}