C#, WPF, ソフトウェア開発

VisualStudio2019から、BlendSDKが提供されなくなった為、
Microsoft.Xaml.Behaviors.Wpfへ移行する必要がある。

BlendSDK

xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

Microsoft.Xaml.Behaviors.Wpf

xmlns:ei="http://schemas.microsoft.com/xaml/behaviors"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"

詳細
Open Sourcing XAML Behaviors for WPF | .NET Blog

C#, WPF

Livetを用いてViewModelからViewを操作する為に
WindowInteractionMessageActionを用いる際、
デフォルトのままだとWindowが非アクティブの状態では
正しくメッセージが送信されない(実行されない)。

例として、
OnContentRendered→最小化(非アクティブ化)→3秒待つ→最大化 を行う場合は、
下記のように InvokeActionOnlyWhenWindowIsActive="False" を指定する。

C#, WPF

下記ソースの場合、ボタンを押下すると、行ごとのクラス内のイベントが発生してしまう。

C#, WPF

DataGridのオプションを行選択(SelectionUnit="FullRow")にしている場合でも、
選択したセルに枠が表示されてしまう。

<DataGrid Margin="10" ItemsSource="{Binding Path=ArrayData}" AutoGenerateColumns="False" SelectionMode="Single" SelectionUnit="FullRow">

BorderThicknessを0にすることで、この枠を消去することができる。

        <DataGrid Margin="10" ItemsSource="{Binding Path=ArrayData}" AutoGenerateColumns="False" SelectionMode="Single" SelectionUnit="FullRow">
            <DataGrid.CellStyle>
                <Style TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}">
                    <Setter Property="BorderThickness" Value="0" />
                </Style>
            </DataGrid.CellStyle>

C#, WPF

コンボボックスにMaterial Design In XAML Toolkitを適用すると、
現在選択されている項目が、ドロップダウンの一覧に表示されない形式となる。

C#, WPF, ソフトウェア開発

初期のMainWindow.xaml

<Controls:MetroWindow x:Class="WpfApp6.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:WpfApp6"
        xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
        mc:Ignorable="d"
        Title="MainWindow" Height="200" Width="300">

C#, WPF, ソフトウェア開発

Material Design In XAML ToolkitとMahApps.Metroを用いたマテリアルデザイン風Window の続き)

Material Design In XAML Toolkitのデザイン設定は、モードとカラーがある

●モード
( Light / Dark )

・App.xaml

<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />

・プログラム内から動的変更

// Lightの場合はfalse、Darkの場合はtrue
new PaletteHelper().SetLightDark(true);

●カラー
( Amber / Blue / BlueGrey / Brown / Cyan / DeepOrange / DeepPurple /
Green / Grey / Indigo / LightBlue / LightGreen / Lime / Orange / Pink /
Purple / Red / Teal / Yellow )

・App.xaml

<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.Indigo.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Indigo.xaml" />

・プログラム内から動的変更

new PaletteHelper().ReplacePrimaryColor("Amber");
new PaletteHelper().ReplaceAccentColor("LightGreen");

なお、名前の一覧は MaterialDesignColors.SwatchesProvider にて取得可能。

MahApps.Metroにもモードとカラーがある

●モード
( BaseLight / BaseDark )
●カラー
( Red / Green / Blue / Purple / Orange / Lime / Emerald / Teal / Cyan /
Cobalt / Indigo / Violet / Pink / Magenta / Crimson / Amber / Yellow /
Brown / Olive / Steel / Mauve / Taupe / Sienna )

        public MainWindow()
        {
            InitializeComponent();

            ThemeManager.ChangeAppStyle(
                Application.Current,
                ThemeManager.GetAccent("Sienna"),
                ThemeManager.GetAppTheme("BaseLight")
                );
        }

MahApps.Metroのスタイルの詳細はこちらを参照

C#, WPF, ソフトウェア開発

Material Design In XAML Toolkitを用いることで、簡単にWindowをマテリアルデザイン風にすることができる。
さらにMahApps.Metroを導入することで、細かいカスタマイズや拡張コントロールを利用できる。

C#, WPF, ソフトウェア開発

メソッドの引数・返り値にジェネリックを用いることで、
型が異なる処理を同一のメソッドで行うことができる

サンプルデータクラス

    public class clsIntStruct
    {
        public int Value1 { get; set; }
        public int Value2 { get; set; }
    }

    public class clsDoubleStruct
    {
        public double Value3 { get; set; }
        public double Value4 { get; set; }
    }

処理クラス

引数に渡されたクラスを、10個の配列にして返している
その際、渡されたクラス内のプロパティを動的に取得、格納している

    public class clsToArray
    {
        public static List<T> StructToArray<T>(T objStrust) where T:class, new()
        {
            List<T> arrayResult = new List<T>();

            for(int intCount = 0; intCount < 10; intCount++)
            {
                T objWork = new T();

                foreach (PropertyInfo objInfo in objStrust.GetType().GetProperties())
                {
                    objInfo.SetValue(objWork, objInfo.GetValue(objStrust));
                }

                arrayResult.Add(objWork);
            }

            return arrayResult;
        }
    }

呼び出しサンプル

        public MainWindow()
        {
            InitializeComponent();

            // Int型のクラス
            clsIntStruct objInt = new clsIntStruct();
            objInt.Value1 = 3;
            objInt.Value2 = 10;

            List<clsIntStruct> resultInt = clsToArray.StructToArray(objInt);

            // Double型のクラス
            clsDoubleStruct objDouble = new clsDoubleStruct();
            objDouble.Value3 = 1.5;
            objDouble.Value4 = 9.7;

            List<clsDoubleStruct> resultDouble = clsToArray.StructToArray(objDouble);

        }

C#, WPF, ソフトウェア開発

Windows7のVirtualStoreが登場する前は、
アプリケーションデータをEXEと同ディレクトリに設置しすることで、
アプリケーションを削除したい際、ディレクトリごと削除するだけで
環境を汚さずに処理することができた。

しかしVirtualStore実装以降、ProgramFilesディレクトリにアプリケーションを設置した場合、
最新のデータはAppDataに格納されてしまい、ProgramFilesに保存されたデータを手で変更したとしても、
AppDataのデータで上書きされてしまう問題が発生する。

アプリケーションを、 ProgramFilesに設置しようが、他のディレクトリに設置しようが、
AppDataにデータを格納してしまえば良いという考え方もあるが、
なるべくであれば、ProgramFiles以外の場合はEXEと同じディレクトリに設置したいと考え、
下記のようなコードでディレクトリパス取得を行った。