Thread.Sleepの部分はTreeViewItemに大量のDataを入れる関数がありました
TreeViewItem
をひとつ作るのに時間がかかるということでしょうか?
Dispatcher.InvokeをDispatcher.InvokeAsyncに変えて対応してみましたが、結果が同じでした。
InvokeAsync
の中で重い処理があったら、結局当初のコードと同じことになります。
重い部分(だけ)を、別スレッドに回してください。
cs
1using System.Windows;
2using System.Windows.Controls;
3
4namespace Qrub8esahzjqmu3;
5
6public partial class MainWindow : Window
7{
8 public MainWindow() => InitializeComponent();
9
10 private async void Window_Loaded(object sender, RoutedEventArgs e)
11 {
12 for (var i = 1; i < 100; i++)
13 {
14 //var header = GetData(i); // こうだとフリーズ
15 var header = await Task.Run(() => GetData(i));
16 treeView.Items.Add(new TreeViewItem { Header = header, });
17 }
18 }
19
20 private string GetData(int i)
21 {
22 Thread.Sleep(100); // 何か時間がかかるとして
23 return $"Item{i}";
24 }
25}
TreeViewItemを大量に扱う場合はどのように対処すれば良いでしょうか?
それとも「TreeViewItem
を10,000個追加している」ような話でしょうか?
その場合は、TreeView
を仮想化するとかなり改善すると思います。
方法: TreeView のパフォーマンスを改善する - WPF .NET Framework | Microsoft Learn
xml
1<Window
2 x:Class="Qrub8esahzjqmu3.MainWindow"
3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5 Width="800"
6 Height="450"
7 Loaded="Window_Loaded">
8 <Grid>
9 <TreeView x:Name="treeView" VirtualizingStackPanel.IsVirtualizing="True" />
10 </Grid>
11</Window>
cs
1using System.Windows;
2
3namespace Qrub8esahzjqmu3;
4
5public partial class MainWindow : Window
6{
7 public MainWindow() => InitializeComponent();
8
9 private void Window_Loaded(object sender, RoutedEventArgs e)
10 {
11 for (var i = 1; i < 10_000; i++)
12 {
13 treeView.Items.Add($"Item{i}");
14 }
15 }
16}
のコードでは、やはり中でWPFのコントロールに触れなければならず、
さらに子ノードを追加しているとかですかね?
ThemeMode
の確認がてらバインドでの例
xml
1<Window
2 x:Class="Qrub8esahzjqmu3.MainWindow"
3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5 xmlns:local="clr-namespace:Qrub8esahzjqmu3"
6 Width="800"
7 Height="450"
8 Loaded="Window_Loaded">
9 <Grid>
10 <TreeView x:Name="treeView">
11 <TreeView.ItemTemplate>
12 <HierarchicalDataTemplate DataType="local:Node" ItemsSource="{Binding Children}">
13 <TextBlock Text="{Binding Name}" />
14 </HierarchicalDataTemplate>
15 </TreeView.ItemTemplate>
16 </TreeView>
17 </Grid>
18</Window>
cs
1using System.Collections.ObjectModel;
2using System.Windows;
3
4namespace Qrub8esahzjqmu3;
5
6public partial class MainWindow : Window
7{
8 public MainWindow()
9 {
10 InitializeComponent();
11
12#pragma warning disable WPF0001 // 種類は、評価の目的でのみ提供されています。将来の更新で変更または削除されることがあります。続行するには、この診断を非表示にします。
13 Application.Current.ThemeMode = ThemeMode.Dark;
14 }
15
16 private async void Window_Loaded(object sender, RoutedEventArgs e)
17 {
18 treeView.ItemsSource = await Task.Run(() =>
19 {
20 var root = new Node();
21 Add(root, 10, "Node");
22 return root.Children;
23 });
24
25 static Node Add(Node node, int c, string name)
26 {
27 for (var i = 1; i <= c; i++)
28 {
29 var n = new Node() { Name = $"{name}-{i}", };
30 Add(n, c - 1, n.Name);
31 node.Children.Add(n);
32 }
33 return node;
34 }
35 }
36}
37
38public class Node
39{
40 public string? Name { get; set; }
41 public ObservableCollection<Node> Children { get; } = [];
42}
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2024/10/10 10:26 編集
2024/10/10 10:33