通常WPFでListViewを扱う場合、データソースのコレクションとバインドしますが、この記事ではWinFormの用に1件1件ListViewItemを追加してListViewを構築するサンプルコードになります。
実行結果のスクリーンショット
ファイル名:NoXAML25ListView.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UseWPF>true</UseWPF>
</PropertyGroup>
</Project>
ファイル名:App.cs
using System;
using System.Windows;
namespace NoXAML25ListView;
public class App : Application
{
[STAThread]
public static void Main(string[] args)
{
var app = new App();
app.Run();
}
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var win = new MainWindow();
win.Show();
}
}
ファイル名:AssemblyInfo.cs
using System.Windows;
[assembly:ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
ファイル名:MainWindow.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace NoXAML25ListView;
public class MainWindow : Window
{
public class ItemData
{
public object? Name { get; set; }
public long Size { get; set; }
}
public MainWindow()
{
this.Title = "NoXAML ListView";
this.Width = 400;
this.Height = 300;
var gridView = new GridView();
gridView.Columns.Add(new GridViewColumn
{
Header = "Name",
Width = 200,
CellTemplate = CreateNameTemplate()
});
gridView.Columns.Add(new GridViewColumn
{
Header = "Size",
Width = 80,
CellTemplate = CreateSizeTemplate(),
});
var listView = new ListView
{
View = gridView,
};
// アイコン画像生成
var folderIcon = CreateIconBitmap("\uE8B7", 20, Brushes.SteelBlue);
var fileIcon = CreateIconBitmap("\uE8A5", 20, Brushes.Gray);
// Header = StackPanel(icon, text)
listView.Items.Add(new ItemData
{
Name = CreateHeaderPanel(folderIcon, "フォルダ"),
Size = 0,
});
listView.Items.Add(new ItemData
{
Name = CreateHeaderPanel(fileIcon, "ファイル.txt"),
Size = 12345,
});
this.Content = listView;
}
// 画像アイコン+テキストのStackPanel生成
private static StackPanel CreateHeaderPanel(BitmapSource icon, string name)
{
var stack = new StackPanel
{
Orientation = Orientation.Horizontal,
VerticalAlignment = VerticalAlignment.Center,
};
var img = new Image
{
Source = icon,
Width = 20,
Height = 20,
Margin = new Thickness(0, 0, 4, 0),
VerticalAlignment = VerticalAlignment.Center,
};
var text = new TextBlock
{
Text = name,
VerticalAlignment = VerticalAlignment.Center,
};
stack.Children.Add(img);
stack.Children.Add(text);
return stack;
}
// DataTemplateでHeader(UIElement)を表示
private static DataTemplate CreateNameTemplate()
{
var dt = new DataTemplate(typeof(ItemData));
var factory = new FrameworkElementFactory(typeof(ContentPresenter));
factory.SetBinding(ContentPresenter.ContentProperty, new System.Windows.Data.Binding("Name"));
dt.VisualTree = factory;
return dt;
}
// 文字→BitmapSource
private BitmapSource CreateIconBitmap(string iconText, int size, Brush fg)
{
var font = new Typeface(new FontFamily("Segoe MDL2 Assets"), FontStyles.Normal, FontWeights.Normal, FontStretches.Normal);
var formatted = new FormattedText(
iconText,
System.Globalization.CultureInfo.InvariantCulture,
FlowDirection.LeftToRight,
font,
size,
fg,
VisualTreeHelper.GetDpi(this).PixelsPerDip);
var width = (int)formatted.Width + 2;
var height = (int)formatted.Height + 2;
var dv = new DrawingVisual();
using (var dc = dv.RenderOpen())
{
dc.DrawText(formatted, new Point(1, 1));
}
var bmp = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
bmp.Render(dv);
return bmp;
}
// Size列用DataTemplate(右寄せTextBlock)
private static DataTemplate CreateSizeTemplate()
{
var dt = new DataTemplate(typeof(MainWindow.ItemData));
var dock = new FrameworkElementFactory(typeof(DockPanel));
var factory = new FrameworkElementFactory(typeof(TextBlock));
factory.SetBinding(TextBlock.TextProperty, new System.Windows.Data.Binding("Size"));
factory.SetValue(TextBlock.TextAlignmentProperty, TextAlignment.Right);
factory.SetValue(TextBlock.PaddingProperty, new Thickness(0,0,16,0)); // 右端に余白調整
factory.SetValue(TextBlock.WidthProperty, 70.0); // 右端に余白調整
factory.SetValue(TextBlock.HorizontalAlignmentProperty, HorizontalAlignment.Right);
factory.SetValue(TextBlock.VerticalAlignmentProperty, VerticalAlignment.Top);
dock.AppendChild(factory);
dt.VisualTree = dock;
return dt;
}
}
コメント