private Assembly AssemblyData = System.Reflection.Assembly.GetEntryAssembly();
// タイトル名
AssemblyData.GetName().Name;
// 会社名
GetCustomAttribute<AssemblyCompanyAttribute>().Company;
private T GetCustomAttribute<T>() where T : Attribute
{
return (T)Attribute.GetCustomAttribute(AssemblyData, typeof(T));
}
呼び出し元のAssemblyからタイトル名・会社名を取得する
文字コードを考慮してWebClientでサイトソースを取得する
private async Task<string> GetSiteSource(string url, Uri reffrrer = null)
{
using (System.Net.WebClient objWebClient = new System.Net.WebClient())
{
if(reffrrer != null)
objWebClient.Headers.Add(HttpRequestHeader.Referer, reffrrer.ToString());
objWebClient.Headers.Add(HttpRequestHeader.UserAgent, strUserAgent);
objWebClient.Encoding = System.Text.Encoding.UTF8;
string strSource = await objWebClient.DownloadStringTaskAsync(url);
ContentType contentType = new ContentType(objWebClient.ResponseHeaders["Content-Type"]);
switch(contentType.CharSet.ToLower().Replace("-", ""))
{
case "utf8":
break;
case "eucjp":
objWebClient.Encoding = System.Text.Encoding.GetEncoding("euc-jp");
strSource = await objWebClient.DownloadStringTaskAsync(url);
break;
case "shiftjis":
objWebClient.Encoding = System.Text.Encoding.GetEncoding("shift-jis");
strSource = await objWebClient.DownloadStringTaskAsync(url);
break;
default:
break;
}
return strSource;
}
}
画像URLからBase64文字列を作成
public static class ImageURLToBase64
{
/// <summary>
/// 画像URLからBase64文字列を取得
/// </summary>
/// <param name="strImgeURL"></param>
/// <returns></returns>
public static async Task<string> GetBase64(string strImgeURL)
{
string strResult = string.Empty;
byte[] bs = null;
using (WebClient objWebClient = new WebClient())
{
bs = await objWebClient.DownloadDataTaskAsync(strImgeURL);
}
if(bs != null)
{
strResult = Convert.ToBase64String(bs);
string strType = GetImageTypeFromByte(bs);
if (strType != string.Empty)
{
strResult = "data:image/" + strType + ";base64," + strResult;
}
}
return strResult;
}
/// <summary>
/// バイト配列を読んで画像種別を判定
/// </summary>
/// <param name="arrayBytes"></param>
/// <returns></returns>
private static string GetImageTypeFromByte(byte[] arrayBytes)
{
Dictionary<string, string> ImageTypes = new Dictionary<string, string>();
ImageTypes.Add("FFD8", "jpg");
ImageTypes.Add("424D", "bmp");
ImageTypes.Add("474946", "gif");
ImageTypes.Add("89504E470D0A1A0A", "png");
string strBytes = BitConverter.ToString(arrayBytes).Replace("-", string.Empty);
KeyValuePair<string,string> SelectImageType = ImageTypes.Where(x => strBytes.ToLower().StartsWith(x.Key.ToLower())).First();
return SelectImageType.Value.ToString().ToLower();
}
}
BitmapをImageSourceに変換
- Freezeを行わないと、別スレッドから触った際にエラーとなる
- DeleteObjectを行わないとメモリリークが発生する
public static class BitmapToImageSource
{
[DllImport("gdi32.dll", EntryPoint = "DeleteObject")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DeleteObject([In] IntPtr hObject);
/// <summary>
/// BitmapからImageSourceへコンバート
/// </summary>
/// <param name="_Bitmap"></param>
/// <returns></returns>
public static ImageSource Convert(Bitmap _Bitmap)
{
ImageSource objResult = null;
if (_Bitmap != null)
{
var objHandle = _Bitmap.GetHbitmap();
try
{
objResult = Imaging.CreateBitmapSourceFromHBitmap(objHandle, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
objResult.Freeze();
}
finally
{
DeleteObject(objHandle);
}
}
return objResult;
}
}
ListViewのマウスオーバー時・選択時の色を消す
MainWindow.xaml
<Window x:Class="WpfApp8.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:WpfApp8"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<ListView ItemsSource="{Binding Path=ArrayData}">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<!-- ボーダーの設定 -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContentControl}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<!-- 選択時の背景色 -->
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Transparent" />
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Window>
ListViewを横並びにする
MainWindow.xaml
<Window x:Class="WpfApp8.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:WpfApp8"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel Orientation="Horizontal">
<!-- 縦並び -->
<ListView ItemsSource="{Binding Path=ArrayData}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<!-- 横並び -->
<ListView ItemsSource="{Binding Path=ArrayData}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</Window>
オブジェクトのシリアライズ(Object→String)・デシリアライズ(String→Object)
アプリケーション終了時に、構造体の変数をシリアライズ化(文字列化)して設定ファイルに書き込み、
次回起動時にシリアライズ解除(オブジェクト化)することで、変数をまるごと維持することができる。
using System.Web.UI;
namespace CommonLibrary
{
public static class ObjectSerialize
{
private static ObjectStateFormatter formatter = new ObjectStateFormatter();
/// <summary>
/// オブジェクトのシリアライズ
/// </summary>
/// <param name="objTarget"></param>
/// <returns></returns>
public static string Serialize(object objTarget)
{
return formatter.Serialize(objTarget);
}
/// <summary>
/// オブジェクトのデシリアライズ
/// </summary>
/// <param name="strTarget"></param>
/// <returns></returns>
public static object Deserialize(string strTarget)
{
return (strTarget == string.Empty) ? null : formatter.Deserialize(strTarget);
}
}
}
TreeViewの多階層をBindで実装、スタイルを指定する
- TreeView の ItemsSource に全体の配列をBindし、 HierarchicalDataTemplate の ItemsSource に、子要素をBindする
- 各項目のスタイルは、TreeView.ItemContainerStyle に設定する
- 子要素が1つでもあれば、展開(>)ボタンが表示される
MainWindow.xaml
<Window x:Class="WpfApp7.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:WpfApp7"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<TreeView ItemsSource="{Binding Mode=OneWay}">
<TreeView.Style>
<!-- TreeView自体のスタイル -->
<Style TargetType="{x:Type TreeView}" BasedOn="{StaticResource MaterialDesignTreeView}">
<Setter Property="Background" Value="#FFF0F0F0"/>
</Style>
</TreeView.Style>
<TreeView.ItemContainerStyle>
<!-- TreeViewの各項目のスタイル -->
<Style TargetType="{x:Type TreeViewItem}" BasedOn="{StaticResource MaterialDesignTreeViewItem}">
<Setter Property="Padding" Value="0"/>
<Setter Property="Background" Value="{Binding Path=BackColor, Mode=OneTime}"/>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<!-- HierarchicalDataTemplate の ItemSource に、子階層をBind -->
<HierarchicalDataTemplate DataType="local:TreeDataStructure" ItemsSource="{Binding Path=SubData, Mode=OneWay}">
<Label Content="{Binding Path=LabelTest, Mode=OneWay}" Foreground="{Binding Path=ForeColor, Mode=OneTime}"/>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
</Window>
TreeViewの表示パフォーマンスの改善
TreeViewの表示件数が多くなると、ノードのExpand時、表示に時間がかかるようになる。
VirtualizingStackPanel.IsVirtualizing 及び VirtualizingStackPanel.VirtualizationMode を
設定することで、パフォーマンスは改善する。
(代償として、展開時のなめらかさは落ちる。)
<TreeView>
<TreeView.Style>
<Style TargetType="{x:Type TreeView}" BasedOn="{StaticResource MaterialDesignTreeView}">
<Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"/>
<Setter Property="VirtualizingStackPanel.VirtualizationMode" Value="Recycling"/>
</Style>
</TreeView.Style>
<TreeViewItem>
<TreeViewItem.Header>
<TextBlock Text="Root"/>
</TreeViewItem.Header>
<TextBlock Text="1-1"/>
<TextBlock Text="1-2"/>
<TreeViewItem>
<TreeViewItem.Header>
<TextBlock Text="1-3"/>
</TreeViewItem.Header>
<TextBlock Text="1-3-1"/>
<TextBlock Text="1-3-2"/>
<TreeViewItem>
<TreeViewItem.Header>
<TextBlock Text="1-3-3"/>
</TreeViewItem.Header>
<TextBlock Text="1-3-3-1"/>
<TextBlock Text="1-3-3-2"/>
</TreeViewItem>
</TreeViewItem>
<TreeViewItem>
<TreeViewItem.Header>
<TextBlock Text="1-4"/>
</TreeViewItem.Header>
<TextBlock Text="1-4-1"/>
<TextBlock Text="1-4-2"/>
</TreeViewItem>
</TreeViewItem>
</TreeView>
よく使う初期環境 MaterialDesignThemes 3.1.3 対応版
よく使う初期環境 のMaterialDesignThemes 3.1.3 対応版
- ControlzEx 4.3.2
- LivetCask 3.2.3.1
- LivetCask.Behaviors 3.2.3.1
- LivetCask.Collections 3.2.3.1
- LivetCask.Converters 3.2.3.1
- LivetCask.Core 3.2.3.1
- LivetCask.EventListeners 3.2.3.1
- LivetCask.Messaging 3.2.3.1
- LivetCask.Mvvm 3.2.3.1
- MahApps.Metro 2.2.0
- MaterialDesignColors 1.2.6
- MaterialDesignThemes 3.1.3
- MaterialDesignThemes.MahApps 0.1.4
- Microsoft.Xaml.Behaviors.Wpf 1.1.19