Winメモ　GUIフロントエンドひな型

# <i class="fa fa-cubes" style="font-size:1em;"></i> 概要
コマンドラインツールなどのGUIフロントエンドとして使えそうな雛型。
エクスプローラーなどからリストボックスに処理したいファイルをドラッグ＆ドロップし、実行ボタンを押せばプログラムの引数にオプションとファイルパスを渡して起動します。

カスタマイズしてお使いください。

# <i class="fa fa-cubes" style="font-size:1em;"></i> 画面イメージ
![w02-01.png](https://qiita-image-store.s3.amazonaws.com/0/142879/8cd15f7a-6b0d-d356-c10a-4ce87ee563b0.png)

![w02-02.png](https://qiita-image-store.s3.amazonaws.com/0/142879/678f2f04-17c2-f115-9885-dc0c80925cb8.png)



# <i class="fa fa-file-text-o" style="font-size:1em;"></i> コード

```CSharp:MainWindow.xaml.cs
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Input;

namespace GUIFrontend
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        static readonly string DROP_NAVI_TEXT = "ここにファイルをドロップしてください。";

        public static readonly ICommand ExecCommand = new RoutedCommand(nameof(ExecCommand), typeof(MainWindow));

        public ObservableCollection<string> DropListItems { get; set; }

        public MainWindow()
        {
            InitializeComponent();

            this.InitItemBindings();
            this.InitCommandBindings();
        }

        private void InitItemBindings()
        {
            this.DropListItems = new ObservableCollection<string>();
            Enumerable.Range(0, 5).ToList().ForEach(x => this.DropListItems.Add(DROP_NAVI_TEXT));
            dropList.ItemsSource = this.DropListItems;
        }

        private void InitCommandBindings()
        {
            this.CommandBindings.Add(new CommandBinding(ExecCommand, Exec_Execute, Exec_CanExecute));
        }

        /// <summary>
        /// プログラム実行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Exec_Execute(object sender, RoutedEventArgs e)
        {
            string option = optionText.Text.Trim();

            if (execOnceCheck.IsChecked == true)
            {
                string args = option + " ";
                // ドロップファイルをまとめて引数に渡し、1回だけプログラム実行
                foreach (var item in this.DropListItems)
                {
                    args += $"\"{item}\" ";
                }

                System.Diagnostics.Process.Start(commandText.Text, args);
            }
            else
            {
                // ドロップファイル数分、プログラム実行
                foreach (var item in this.DropListItems)
                {
                    System.Diagnostics.Process.Start(commandText.Text, $"{option} \"{item}\"");
                }
            }
        }

        private void Exec_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            // プログラムパスが入力されていて、
            // ファイルがドロップされていれば実行ボタン有効
            if (commandText.Text != "" &&
                this.DropListItems.Any() &&
                this.DropListItems[0] != DROP_NAVI_TEXT)
            {
                e.CanExecute = true;
            }
        }

        /// <summary>
        /// ファイルドロップ
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dropList_Drop(object sender, DragEventArgs e)
        {
            string[] files = e.Data.GetData(DataFormats.FileDrop) as string[];

            if (files != null)
            {
                this.DropListItems.Clear();
                foreach (var s in files)
                {
                    this.DropListItems.Add(s);
                }

                execOnceCheck.Focus();
            }
        }

        private void dropList_PreviewDragOver(object sender, DragEventArgs e)
        {
            // ドラッグ中のデータの形式チェック
            if (e.Data.GetDataPresent(DataFormats.FileDrop, true))
            {
                e.Effects = DragDropEffects.Copy;
            }
            else
            {
                e.Effects = DragDropEffects.None;
            }
            e.Handled = true;
        }
    }
}
```

```Xml:MainWindow.xaml
<Window x:Class="GUIFrontend.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:GUIFrontend"
        mc:Ignorable="d"
        ResizeMode="CanResizeWithGrip"
        Title="GUIフロントエンド" Height="350" Width="525">
    <Window.Resources>
        <ScaleTransform x:Key="DoubleScale" ScaleX="2" ScaleY="2" />
        <!-- 大きなボタン -->
        <Style x:Key="BigButton" TargetType="{x:Type Button}">
            <Setter Property="LayoutTransform" Value="{StaticResource DoubleScale}"/>
        </Style>
        <!-- テキストのスタイル -->
        <Style TargetType="{x:Type TextBlock}">
            <Setter Property="VerticalAlignment" Value="Center"/>
            <Setter Property="Margin" Value="10,0,5,0"/>
        </Style>
    </Window.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="auto"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="auto"/>
        </Grid.ColumnDefinitions>

        <!-- 1行目 -->
        <TextBlock Text="プログラム" />
        <TextBox
            Name="commandText"
            Text="notepad.exe"
            Grid.Column="1" Grid.ColumnSpan="2" Margin="10"/>

        <!-- 2行目 -->
        <TextBlock Text="オプション" Grid.Row="1"/>
        <TextBox
            Name="optionText"
            Text=""
            Grid.Row="1" Grid.Column="1" Margin="10"/>
        <CheckBox
            Name="execOnceCheck"
            Content="まとめて1回で実行"
            ToolTip="複数ファイルをまとめてプログラムに渡すか、1ファイルずつプログラムに渡して実行するか選択します。"
            IsChecked="True"
            Grid.Row="1" Grid.Column="2" Margin="10"/>

        <!-- 3行目 -->
        <Button
            Name="execButton"
            Content="実行"
            IsDefault="True"
            Command="{x:Static local:MainWindow.ExecCommand}"
            Style="{StaticResource BigButton}"
            Grid.Row="2" Grid.ColumnSpan="3" Width="100" Margin="10"/>

        <!-- 4行目 -->
        <ListBox
            Name="dropList"
            AllowDrop="True"
            Grid.Row="3" Grid.ColumnSpan="3"
            Drop="dropList_Drop"
            PreviewDragOver="dropList_PreviewDragOver"/>
    </Grid>
</Window>
```

# <i class="fa fa-cubes" style="font-size:1em;"></i> 動作確認した環境
* Windows 8.1, .NET Framework 4.5, Visual Studio 2015(WPFアプリケーション)
* Windows 10, .NET Framework 4.5.2, Visual Studio 2015(WPFアプリケーション)