WPFでファイルやフォルダアイコンが必要ですが、アイコンファイルを用意するのも面倒なので、テキストから生成する方法を調べてみました。
プロジェクト作成
cd (mkdir WpfFileIcon01)
dotnet new wpf -f net8.0
rm MainWindow.xaml.cs
rm *.xaml
ソースコード
ファイル名:WpfFileIcon01.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UseWPF>true</UseWPF>
<StartupObject>WpfFileIcon01.App</StartupObject>
</PropertyGroup>
</Project>
ファイル名:App.xaml.cs
using System.Windows;
namespace WpfFileIcon01;
public partial class App : Application
{
[STAThread]
public static void Main()
{
var window = new MainWindow();
var app = new App();
app.Run(window);
}
}
ファイル名:MainWindow.cs
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace WpfFileIcon01;
public enum DefaultIconType
{
Folder,
File,
Error
}
public class MainWindow : Window
{
private static BitmapImage CreateDefaultIcon(DefaultIconType type)
{
var width = 256;
var height = 256;
var dv = new DrawingVisual();
using (var dc = dv.RenderOpen())
{
Brush bg = type switch
{
DefaultIconType.Folder => Brushes.Goldenrod,
DefaultIconType.File => Brushes.LightSlateGray,
DefaultIconType.Error => Brushes.DarkRed,
_ => Brushes.Gray
};
string text = type switch
{
DefaultIconType.Folder => "📁",
DefaultIconType.File => "📄",
DefaultIconType.Error => "❌",
_ => "?"
};
// 背景
dc.DrawRectangle(bg, null, new Rect(0, 0, width, height));
// テキスト
var formatted = new FormattedText(
text,
System.Globalization.CultureInfo.InvariantCulture,
FlowDirection.LeftToRight,
new Typeface("Segoe UI Emoji"),
100,
Brushes.White,
VisualTreeHelper.GetDpi(dv).PixelsPerDip
);
dc.DrawText(formatted, new Point((width - formatted.Width) / 2, (height - formatted.Height) / 2));
}
var rtb = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
rtb.Render(dv);
// Encode to PNG in memory
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(rtb));
using var ms = new MemoryStream();
encoder.Save(ms);
ms.Position = 0;
var image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.StreamSource = ms;
image.EndInit();
return image;
}
StackPanel _stackPanel = new()
{
Orientation = Orientation.Horizontal,
};
Image _fileImage = new()
{
Width = 256,
Height = 256,
};
Image _folderImage = new()
{
Width = 256,
Height = 256,
};
Image _errorImage = new()
{
Width = 256,
Height = 256,
};
public MainWindow()
{
Title = "アイコンを表示";
Width = 768;
Height = 300;
_fileImage.Source = CreateDefaultIcon(DefaultIconType.File);
_folderImage.Source = CreateDefaultIcon(DefaultIconType.Folder);
_errorImage.Source = CreateDefaultIcon(DefaultIconType.Error);
_stackPanel.Children.Add(_fileImage);
_stackPanel.Children.Add(_folderImage);
_stackPanel.Children.Add(_errorImage);
Content = new Grid { Children = { _stackPanel } };
}
}
実行
dotnet run
アイコン用画像が表示されます。
コメント