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