😎

AvaloniaUIのListBoxをコードから設定する

2024/04/03に公開

やりたいこと

AvaloniaUIの各ListBoxをC#コードで操作したい。
axamlでのBinding/Style指定を使わずにコードから操作したい場合の実装方法

使用環境

Windows 11 : Home 22H2 + Visual Studio Community 2022(64bit)
Linuxテスト環境 : 上記Windows上のWSL2 Ubuntsu 22.04.2 LTS
Visual Studio2022, AvaloniaUI 11.0.2

実装例

ListBoxに入れるItemをItemsにAddする。
要素行の高さを設定するには追加する各ItemのHeightを設定するだけでなく、ListBoxItemのStyleのMinHeightPropertyも設定する必要がある。

※追記 この手法でItem追加すると、ListBoxのScrollが発生したときに
"the control already has a visual parent" exceptionが発生する。
https://github.com/AvaloniaUI/Avalonia/issues/4265

上記ではVirtualizationModeをNoneにするWorkaroundが提示されているが、VirtualizationModeはその後のversionで廃止されている。

https://github.com/AvaloniaUI/Avalonia/pull/9677

ObservableCollection<ListBoxItem>をListBox0.ItemsSourceに追加し、ListBoxItemを追加。ListBoxItemのContentにListBoxに入れるItemを設定する必要がありそう。

        Style style = new Style();
        style.Selector = ((Selector?)null).OfType(typeof(ListBoxItem));
        style.Add(new Setter( Layoutable.MinHeightProperty,8.0));
        style.Add(new Setter(Layoutable.HeightProperty, 15.0));
        ListBox0.Styles.Add(style);

        {
            var textBlock = new TextBlock();
            textBlock.Text = "AAA";
            textBlock.Height = 10;
            textBlock.MinHeight = 10;
            textBlock.FontSize = 8;
            textBlock.Margin = new Avalonia.Thickness(0, 0, 0, 0);
            ListBox0.Items.Add(textBlock);
        }

        {
            var textBlock = new TextBlock();
            {
                Run run = new Run("ABC");
                run.Foreground = new SolidColorBrush(Avalonia.Media.Colors.Red);
                textBlock.Inlines.Add(run);
                textBlock.Height = 10;
                textBlock.MinHeight = 10;
                textBlock.Margin = new Avalonia.Thickness(0, 0, 0, 0);
                textBlock.FontSize = 10;
            }
            {
                Run run = new Run("DEF");
                textBlock.Inlines.Add(run);
                textBlock.Height = 10;
                textBlock.MinHeight = 10;
                textBlock.Margin = new Avalonia.Thickness(0, 0, 0, 0);
                textBlock.FontSize = 10;
            }
            ListBox0.Items.Add(textBlock);
        }

Discussion