20200804のC#に関する記事は7件です。

Prism小さなサンプル

■環境

  • Windows 10
  • Visual Studio Community 2019 (Version 16.6.5)
  • Prism Template Pack 2.2.1
  • .NET Core 3.x

■STEP0. インストール、プロジェクト作成

◇0-1. 最初の作業

メニューの拡張機能 - 拡張機能の管理Prism Template Packをインストール。
Visual Studio再起動。

◇0-2. STEPごとにやる作業

新しいプロジェクトでPrism Blank App (.NET Core)を選択。
プロジェクト名を付ける(プログラム例では PrismStep● という名前でSTEPごとにプロジェクトを作成している)。
PRISM PROJECT WIZARDでコンテナにUnityを選択。

ソリューションエクスプローラーでプロジェクトを右クリック、プロパティを選択。
対象のフレームワークが.NET Core 3.0になっていたら.NET Core 3.1に変更。

◇0-3. 目次

■STEP1. バインディング

実行イメージ
s1.png

◇1-1. ViewModelの記述

バインド用の変数はコードスニペットpropp、コマンドはcmdを使うと楽。

MainWindowViewModel.cs
using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Collections.ObjectModel;

namespace PrismStep1.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private string _title = "バインディングの確認";
        /// <summary>
        /// タイトル
        /// </summary>
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        private string _systemDateText = "---";
        /// <summary>
        /// システム日付テキスト
        /// </summary>
        public string SystemDateText
        {
            get { return _systemDateText; }
            set { SetProperty(ref _systemDateText, value); }
        }

        private ObservableCollection<string> _fruits = new ObservableCollection<string>();
        /// <summary>
        /// 果物リスト
        /// </summary>
        public ObservableCollection<string> Fruits
        {
            get { return _fruits; }
            set { SetProperty(ref _fruits, value); }
        }

        private DelegateCommand _setSystemDateCommand;
        /// <summary>
        /// システム日付設定コマンド
        /// </summary>
        public DelegateCommand SetSystemDateCommand =>
            _setSystemDateCommand ?? (_setSystemDateCommand = new DelegateCommand(ExecuteSetSystemDateCommand));

        /// <summary>
        /// システム日付設定処理
        /// </summary>
        void ExecuteSetSystemDateCommand()
        {
            SystemDateText = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
        }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public MainWindowViewModel()
        {
            _fruits.Add("りんご");
            _fruits.Add("梨");
            _fruits.Add("ブドウ");
            _fruits.Add("桃");
            _fruits.Add("ブルーベリー");
        }
    }
}

◇1-2. Viewの記述

MainWindow.xaml
<Window
    x:Class="PrismStep1.Views.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:prism="http://prismlibrary.com/"
    Title="{Binding Title}"
    Width="350"
    Height="200"
    prism:ViewModelLocator.AutoWireViewModel="True">
    <StackPanel>
        <Button
            Margin="5"
            Command="{Binding SetSystemDateCommand}"
            Content="システム日時" />
        <!--  システム日時表示エリア  -->
        <TextBlock Margin="5" Text="{Binding SystemDateText}" />
        <!--  果物リスト  -->
        <ListBox
            Height="80"
            Margin="5"
            ItemsSource="{Binding Fruits}" />
        <ContentControl prism:RegionManager.RegionName="ContentRegion" />
    </StackPanel>
</Window>

■STEP2. 別画面ポップアップ表示

実行イメージ
s2.png

◇2-1. 別画面の追加

ソリューションエクスプローラーでViewsフォルダを右クリック、追加 - 新しい項目を選択。
Prism UserControl (WPF)を選択し、名前にSubWindow.xamlと入力し追加ボタン選択。
自動的にViewModelのファイルも生成される。

◇2-2. メイン画面

◎2-2-1. ViewModelの記述

MainWindowViewModel.cs
using Prism.Commands;
using Prism.Mvvm;
using Prism.Services.Dialogs;

namespace PrismStep2.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private readonly IDialogService _dialogService;

        private string _title = "別画面の表示";
        /// <summary>
        /// タイトル
        /// </summary>
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        private DelegateCommand _showCommand;
        /// <summary>
        /// 画面表示コマンド
        /// </summary>
        public DelegateCommand ShowCommand =>
            _showCommand ?? (_showCommand = 
                new DelegateCommand(ExecuteShowCommand));

        /// <summary>
        /// 画面表示処理
        /// </summary>
        void ExecuteShowCommand()
        {
            _dialogService.Show(
                nameof(Views.SubWindow),    // 表示するビュー名
                null,                       // 渡すパラメータ
                null);                      // 閉じた後の処理
        }

        private DelegateCommand _showDialogCommand;
        /// <summary>
        /// 画面モーダル表示コマンド
        /// </summary>
        public DelegateCommand ShowDialogCommand =>
            _showDialogCommand ?? (_showDialogCommand = 
                new DelegateCommand(ExecuteShowDialogCommand));

        /// <summary>
        /// 画面モーダル表示処理
        /// </summary>
        void ExecuteShowDialogCommand()
        {
            _dialogService.ShowDialog(
                nameof(Views.SubWindow),    // 表示するビュー名
                null,                       // 渡すパラメータ
                null);                      // 閉じた後の処理
        }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="dialogService"></param>
        public MainWindowViewModel(IDialogService dialogService)
        {
            _dialogService = dialogService;
        }
    }
}

◎2-2-2. Viewの記述

MainWindow.xaml
<Window
    x:Class="PrismStep2.Views.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:prism="http://prismlibrary.com/"
    Title="{Binding Title}"
    Width="350"
    Height="150"
    prism:ViewModelLocator.AutoWireViewModel="True">
    <Window.Resources>
        <Style TargetType="Button">
            <Setter Property="Margin" Value="5" />
        </Style>
    </Window.Resources>
    <StackPanel>
        <Button Command="{Binding ShowCommand}" Content="画面表示" />
        <Button Command="{Binding ShowDialogCommand}" Content="画面モーダル表示" />
        <ContentControl prism:RegionManager.RegionName="ContentRegion" />
    </StackPanel>
</Window>

◇2-3. 子画面

◎2-3-1. ViewModelの記述

IDialogAwareを実装する。

SubWindowViewModel.cs
using Prism.Mvvm;
using Prism.Services.Dialogs;
using System;

namespace PrismStep2.ViewModels
{
    public class SubWindowViewModel : BindableBase, IDialogAware
    {
        public SubWindowViewModel()
        {

        }

        #region IDialogAwareの実装

        public string Title => "子画面";

        public event Action<IDialogResult> RequestClose;

        public bool CanCloseDialog()
        {
            return true;
        }

        public void OnDialogClosed()
        {
        }

        public void OnDialogOpened(IDialogParameters parameters)
        {
        }

        #endregion
    }
}

◎2-3-2. Viewの記述

SubWindow.xaml
<UserControl
    x:Class="PrismStep2.Views.SubWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:prism="http://prismlibrary.com/"
    prism:ViewModelLocator.AutoWireViewModel="True">
    <Grid>
        <TextBlock FontSize="70" Text="*** 子画面 ***" />
    </Grid>
</UserControl>

◇2-4. Appクラス

App.xaml.cs
using Prism.Ioc;
using PrismStep2.ViewModels;
using PrismStep2.Views;
using System.Windows;

namespace PrismStep2
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App
    {
        protected override Window CreateShell()
        {
            return Container.Resolve<MainWindow>();
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            // 子画面をコンテナに登録
            containerRegistry.RegisterDialog<SubWindow, SubWindowViewModel>();
        }
    }
}

■STEP3. 呼び出す画面にパラメータを渡す

実行イメージ
s3.png

◇3-1. 別画面の追加

STEP2と同様、ViewsフォルダにPrism UserControl (WPF)を名前SubWindow.xamlで追加。

◇3-2. メイン画面

◎3-2-1. ViewModelの記述

DialogParametersのインスタンスにパラメータを追加し、ダイアログ表示時に渡す。

MainWindowViewModel.cs
using Prism.Commands;
using Prism.Mvvm;
using Prism.Services.Dialogs;
using System;

namespace PrismStep3.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private readonly IDialogService _dialogService;

        private string _title = "別画面にパラメータを渡す";
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        private string _input1 = "abcde";
        /// <summary>
        /// 入力パラメータ
        /// </summary>
        public string Input1
        {
            get { return _input1; }
            set { SetProperty(ref _input1, value); }
        }

        private DelegateCommand _showCommand;
        /// <summary>
        /// 別画面表示コマンド
        /// </summary>
        public DelegateCommand ShowCommand =>
            _showCommand ?? (_showCommand = new DelegateCommand(ExecuteShowCommand));

        /// <summary>
        /// 別画面表示処理
        /// </summary>
        void ExecuteShowCommand()
        {
            var param = new DialogParameters();
            param.Add("Param1", Input1);
            param.Add("Param2", 456);
            param.Add("Param3", DateTime.Now);

            _dialogService.ShowDialog(
                nameof(Views.SubWindow),    // 表示するビュー名
                param,                      // 渡すパラメータ
                null);                      // 閉じた後の処理
        }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="dialogService"></param>
        public MainWindowViewModel(IDialogService dialogService)
        {
            _dialogService = dialogService;
        }
    }
}

◎3-2-2. Viewの記述

MainWindow.xaml
<Window
    x:Class="PrismStep3.Views.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:prism="http://prismlibrary.com/"
    Title="{Binding Title}"
    Width="350"
    Height="150"
    prism:ViewModelLocator.AutoWireViewModel="True">
    <StackPanel>
        <TextBox
            Width="100"
            Margin="5"
            Text="{Binding Input1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        <Button
            Margin="5"
            Command="{Binding ShowCommand}"
            Content="別画面表示" />
        <ContentControl prism:RegionManager.RegionName="ContentRegion" />
    </StackPanel>
</Window>

◇3-3. 子画面

◎3-3-1. ViewModelの記述

SubWindowViewModel.cs
using Prism.Mvvm;
using Prism.Services.Dialogs;
using System;

namespace PrismStep3.ViewModels
{
    public class SubWindowViewModel : BindableBase, IDialogAware
    {
        private string _showText;
        /// <summary>
        /// 表示するテキスト(呼び出し元から受け取ったパラメータを加工して表示)
        /// </summary>
        public string ShowText
        {
            get { return _showText; }
            set { SetProperty(ref _showText, value); }
        }

        public SubWindowViewModel()
        {

        }

        #region IDialogAwareの実装

        public string Title => "子画面";

        public event Action<IDialogResult> RequestClose;

        public bool CanCloseDialog()
        {
            return true;
        }

        public void OnDialogClosed()
        {
        }

        /// <summary>
        /// 画面オープン時
        /// </summary>
        /// <param name="parameters"></param>
        public void OnDialogOpened(IDialogParameters parameters)
        {
            // パラメータを取り出す
            var p1 = parameters.GetValue<string>("Param1");
            var p2 = parameters.GetValue<int>("Param2");
            var p3 = parameters.GetValue<DateTime>("Param3");

            ShowText = $"{p1}{p2}{p3:yyyy/MM/dd HH:mm:ss}";
        }

        #endregion
    }
}

◎3-3-2. Viewの記述

SubWindow.xaml
<UserControl
    x:Class="PrismStep3.Views.SubWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:prism="http://prismlibrary.com/"
    Width="500"
    Height="150"
    prism:ViewModelLocator.AutoWireViewModel="True">
    <StackPanel>
        <TextBlock
            Margin="5"
            FontSize="20"
            Text="{Binding ShowText}" />
    </StackPanel>
</UserControl>

◇3-4. Appクラス

STEP2と同様

■STEP4. 呼び出し元画面にパラメータを渡す

実行イメージ
s4-1.png
↓ OK
s4-2.png

◇4-1. 別画面の追加

ViewsフォルダにPrism UserControl (WPF)を名前SubWindow.xamlで追加。

◇4-2. メイン画面

◎4-2-1. ViewModelの記述

MainWindowViewModel.cs
using Prism.Commands;
using Prism.Mvvm;
using Prism.Services.Dialogs;

namespace PrismStep4.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private readonly IDialogService _dialogService;

        private string _title = "別画面からパラメータを受け取る";
        /// <summary>
        /// タイトル
        /// </summary>
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        private string _resultText;
        /// <summary>
        /// 結果テキスト
        /// </summary>
        public string ResultText
        {
            get { return _resultText; }
            set { SetProperty(ref _resultText, value); }
        }

        private DelegateCommand _showCommand;
        /// <summary>
        /// 別画面表示コマンド
        /// </summary>
        public DelegateCommand ShowCommand =>
            _showCommand ?? (_showCommand = new DelegateCommand(ExecuteShowCommand));

        /// <summary>
        /// 別画面表示処理
        /// </summary>
        void ExecuteShowCommand()
        {
            _dialogService.Show(
                nameof(Views.SubWindow),    // 表示するビュー名
                null,                       // 渡すパラメータ
                Dialog_Close);              // 閉じた後の処理
        }

        /// <summary>
        /// 画面を閉じたときの処理
        /// </summary>
        /// <param name="dr"></param>
        private void Dialog_Close(IDialogResult dr)
        {
            if (dr.Result == ButtonResult.OK)
            {
                ResultText = dr.Parameters.GetValue<string>("Param1");
            }
        }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="dialogService"></param>
        public MainWindowViewModel(IDialogService dialogService)
        {
            _dialogService = dialogService;
        }
    }
}

◎4-2-2. Viewの記述

MainWindow.xaml
<Window
    x:Class="PrismStep4.Views.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:prism="http://prismlibrary.com/"
    Title="{Binding Title}"
    Width="350"
    Height="150"
    prism:ViewModelLocator.AutoWireViewModel="True">
    <StackPanel>
        <Button
            Margin="5"
            Command="{Binding ShowCommand}"
            Content="別画面表示" />
        <!--  別画面呼び出し結果を表示  -->
        <TextBlock Margin="5" Text="{Binding ResultText}" />

        <ContentControl prism:RegionManager.RegionName="ContentRegion" />
    </StackPanel>
</Window>

◇4-3. 子画面

◎4-3-1. ViewModelの記述

SubWindowViewModel.cs
using Prism.Commands;
using Prism.Mvvm;
using Prism.Services.Dialogs;
using System;

namespace PrismStep4.ViewModels
{
    public class SubWindowViewModel : BindableBase, IDialogAware
    {
        private string inputParam;
        /// <summary>
        /// 入力パラメータ(呼び出し元に渡す)
        /// </summary>
        public string InputParam
        {
            get { return inputParam; }
            set { SetProperty(ref inputParam, value); }
        }

        private DelegateCommand _okCommand;
        /// <summary>
        /// OKコマンド
        /// </summary>
        public DelegateCommand OkCommand =>
            _okCommand ?? (_okCommand = new DelegateCommand(ExecuteOkCommand));

        /// <summary>
        /// OK時の処理
        /// </summary>
        void ExecuteOkCommand()
        {
            var param = new DialogParameters();
            // 呼び出し元に渡すパラメータを設定
            param.Add("Param1", InputParam);
            // 画面を閉じる
            RequestClose?.Invoke(new DialogResult(ButtonResult.OK, param));
        }

        private DelegateCommand _cancelCommand;
        /// <summary>
        /// キャンセルコマンド
        /// </summary>
        public DelegateCommand CancelCommand =>
            _cancelCommand ?? (_cancelCommand = new DelegateCommand(ExecuteCancelCommand));

        /// <summary>
        /// キャンセル時の処理
        /// </summary>
        void ExecuteCancelCommand()
        {
            // 画面を閉じる
            RequestClose?.Invoke(new DialogResult(ButtonResult.Cancel));
        }

        public SubWindowViewModel()
        {

        }

        #region IDialogAwareの実装

        public string Title => "子画面";

        public event Action<IDialogResult> RequestClose;

        /// <summary>
        /// 画面を閉じられるかどうか
        /// </summary>
        /// <returns></returns>
        public bool CanCloseDialog()
        {
            // 入力があればtrue(true:画面を閉じられる、false:画面を閉じられない)
            return string.IsNullOrEmpty(InputParam) == false;
        }

        public void OnDialogClosed()
        {
        }

        public void OnDialogOpened(IDialogParameters parameters)
        {
        }

        #endregion
    }
}

◎4-3-2. Viewの記述

SubWindow.xaml
<UserControl
    x:Class="PrismStep4.Views.SubWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:prism="http://prismlibrary.com/"
    Width="350"
    Height="150"
    prism:ViewModelLocator.AutoWireViewModel="True">
    <UserControl.Resources>
        <Style TargetType="Button">
            <Setter Property="Margin" Value="5" />
            <Setter Property="Width" Value="100" />
        </Style>
    </UserControl.Resources>

    <StackPanel>
        <TextBlock Margin="5" Text="子画面" />
        <!--  呼び出し元に渡す内容  -->
        <TextBox Margin="5" Text="{Binding InputParam}" />

        <StackPanel Orientation="Horizontal">
            <Button Command="{Binding OkCommand}" Content="OK" />
            <Button Command="{Binding CancelCommand}" Content="キャンセル" />
        </StackPanel>
    </StackPanel>
</UserControl>

◇4-4. Appクラス

STEP2と同様

■STEP5. メッセージボックスを表示

実行イメージ
s5.png

◇5-1. メッセージボックス用画面の追加

ViewsフォルダにPrism UserControl (WPF)を名前MessageWindow.xamlで追加。

◇5-2. メイン画面

◎5-2-1. ViewModelの記述

MainWindowViewModel.cs
using Prism.Commands;
using Prism.Mvvm;
using Prism.Services.Dialogs;
using PrismStep5.Views;

namespace PrismStep5.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        IDialogService _dialogService;

        private string _title = "メッセージボックス表示";
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        private DelegateCommand _showMessageCommand;
        /// <summary>
        /// メッセージ表示コマンド
        /// </summary>
        public DelegateCommand ShowMessageCommand =>
            _showMessageCommand ?? (_showMessageCommand = new DelegateCommand(ExecuteShowCommand));

        /// <summary>
        /// メッセージ表示処理
        /// </summary>
        void ExecuteShowCommand()
        {
            var msg = new DialogParameters();
            msg.Add(nameof(MessageWindowViewModel.Message), "こんにちは");

            // メッセージ表示
            _dialogService.ShowDialog(nameof(MessageWindow), msg, null);
        }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="dialogService"></param>
        public MainWindowViewModel(IDialogService dialogService)
        {
            _dialogService = dialogService;
        }
    }
}

◎5-2-2. Viewの記述

MainWindow.xaml
<Window
    x:Class="PrismStep5.Views.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:prism="http://prismlibrary.com/"
    Title="{Binding Title}"
    Width="300"
    Height="250"
    prism:ViewModelLocator.AutoWireViewModel="True">
    <StackPanel>
        <Button
            Margin="10"
            Command="{Binding ShowMessageCommand}"
            Content="メッセージ表示" />
        <ContentControl prism:RegionManager.RegionName="ContentRegion" />
    </StackPanel>
</Window>

◇5-3. メッセージボックス画面

◎5-3-1. ViewModelの記述

MessageWindowViewModel.cs
using Prism.Commands;
using Prism.Mvvm;
using Prism.Services.Dialogs;
using System;

namespace PrismStep5.ViewModels
{
    public class MessageWindowViewModel : BindableBase, IDialogAware
    {
        private string _message;
        /// <summary>
        /// 表示メッセージ
        /// </summary>
        public string Message
        {
            get { return _message; }
            set { SetProperty(ref _message, value); }
        }

        private DelegateCommand _okCommand;
        /// <summary>
        /// OKコマンド
        /// </summary>
        public DelegateCommand OkCommand =>
            _okCommand ?? (_okCommand = new DelegateCommand(ExecuteOkCommand));

        /// <summary>
        /// OK時の処理
        /// </summary>
        void ExecuteOkCommand()
        {
            RequestClose?.Invoke(new DialogResult(ButtonResult.OK));
        }

        public MessageWindowViewModel()
        {

        }

        #region IDialogAwareの実装

        public string Title => "メッセージ";

        public event Action<IDialogResult> RequestClose;

        public bool CanCloseDialog()
        {
            return true;
        }

        public void OnDialogClosed()
        {
        }

        public void OnDialogOpened(IDialogParameters parameters)
        {
            Message = parameters.GetValue<string>(nameof(Message));
        }

        #endregion
    }
}

◎5-3-2. Viewの記述

MessageWindow.xaml
<UserControl
    x:Class="PrismStep5.Views.MessageWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:prism="http://prismlibrary.com/"
    MinWidth="300"
    prism:ViewModelLocator.AutoWireViewModel="True">
    <prism:Dialog.WindowStyle>
        <Style TargetType="Window">
            <Setter Property="ShowInTaskbar" Value="True" />
            <Setter Property="ResizeMode" Value="NoResize" />
            <Setter Property="SizeToContent" Value="WidthAndHeight" />
        </Style>
    </prism:Dialog.WindowStyle>

    <StackPanel>
        <TextBlock Margin="10" Text="{Binding Message}" />
        <Button
            Width="100"
            Margin="10"
            Command="{Binding OkCommand}"
            Content="OK" />
    </StackPanel>
</UserControl>

◇5-4. Appクラス

App.xaml.cs
using Prism.Ioc;
using PrismStep5.ViewModels;
using PrismStep5.Views;
using System.Windows;

namespace PrismStep5
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App
    {
        protected override Window CreateShell()
        {
            return Container.Resolve<MainWindow>();
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterDialog<MessageWindow, MessageWindowViewModel>();
        }
    }
}

■STEP6. ページ切り替え

実行イメージ
s6-1.png

ページ1ボタン選択
s6-2.png

ページ2ボタン選択
s6-3.png

◇6-1. 切り替え用ページ画面の追加

ViewsフォルダにPrism UserControl (WPF)を名前SubPage1.xaml, SubPage2.xamlで追加。

◇6-2. メイン画面

◎6-2-1. ViewModelの記述

MainWindowViewModel.cs
using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;
using PrismStep6.Views;

namespace PrismStep6.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private readonly IRegionManager _regionManager;

        private string _title = "埋め込み画面サンプル";
        /// <summary>
        /// タイトル
        /// </summary>
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        private DelegateCommand _showPage1Command;
        /// <summary>
        /// ページ1表示コマンド
        /// </summary>
        public DelegateCommand ShowPage1Command =>
            _showPage1Command ?? (_showPage1Command = new DelegateCommand(ExecuteShowPage1Command));

        /// <summary>
        /// ページ1表示処理
        /// </summary>
        void ExecuteShowPage1Command()
        {
            _regionManager.RequestNavigate(
                "ContentRegion",    // xamlのContentControlのRegionNameを指定
                nameof(SubPage1));  // 表示するビュー名
        }

        private DelegateCommand _showPage2Command;
        /// <summary>
        /// ページ2表示コマンド
        /// </summary>
        public DelegateCommand ShowPage2Command =>
            _showPage2Command ?? (_showPage2Command = new DelegateCommand(ExecuteShowPage2Command));

        /// <summary>
        /// ページ2表示処理
        /// </summary>
        void ExecuteShowPage2Command()
        {
            _regionManager.RequestNavigate(
                "ContentRegion",    // xamlのContentControlのRegionNameを指定
                nameof(SubPage2));  // 表示するビュー名
        }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="regionManager"></param>
        public MainWindowViewModel(IRegionManager regionManager)
        {
            _regionManager = regionManager;
        }
    }
}

◎6-2-2. Viewの記述

MainWindow.xaml
<Window
    x:Class="PrismStep6.Views.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:prism="http://prismlibrary.com/"
    Title="{Binding Title}"
    Width="350"
    Height="200"
    prism:ViewModelLocator.AutoWireViewModel="True"
    ResizeMode="CanResizeWithGrip">
    <Window.Resources>
        <Style TargetType="Button">
            <Setter Property="Margin" Value="5,5,0,0" />
            <Setter Property="Padding" Value="15,0" />
        </Style>
    </Window.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>

        <StackPanel Orientation="Horizontal">
            <Button Command="{Binding ShowPage1Command}" Content="ページ1" />
            <Button Command="{Binding ShowPage2Command}" Content="ページ2" />
        </StackPanel>
        <!--  ページ表示エリア  -->
        <ContentControl Grid.Row="1" prism:RegionManager.RegionName="ContentRegion" />
    </Grid>
</Window>

◇6-3. ページ1

◎6-3-1. ViewModelの記述

SubPage1ViewModel.cs
using Prism.Mvvm;

namespace PrismStep6.ViewModels
{
    public class SubPage1ViewModel : BindableBase
    {
        public SubPage1ViewModel()
        {

        }
    }
}

◎6-3-2. Viewの記述

SubPage1.xaml
<UserControl
    x:Class="PrismStep6.Views.SubPage1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:prism="http://prismlibrary.com/"
    prism:ViewModelLocator.AutoWireViewModel="True">
    <Grid Background="AliceBlue">
        <Viewbox>
            <TextBlock Foreground="Blue" Text="ページ1" />
        </Viewbox>
    </Grid>
</UserControl>

◇6-4. ページ2

◎6-4-1. ViewModelの記述

SubPage2ViewModel.cs
using Prism.Mvvm;

namespace PrismStep6.ViewModels
{
    public class SubPage2ViewModel : BindableBase
    {
        public SubPage2ViewModel()
        {

        }
    }
}

◎6-4-2. Viewの記述

SubPage2.xaml
<UserControl
    x:Class="PrismStep6.Views.SubPage2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:prism="http://prismlibrary.com/"
    prism:ViewModelLocator.AutoWireViewModel="True">
    <Grid Background="LightYellow">
        <Viewbox>
            <TextBlock Foreground="Orange" Text="ページ2" />
        </Viewbox>
    </Grid>
</UserControl>

◇6-5. Appクラス

App.xaml.cs
using Prism.Ioc;
using PrismStep6.Views;
using System.Windows;

namespace PrismStep6
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App
    {
        protected override Window CreateShell()
        {
            return Container.Resolve<MainWindow>();
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterForNavigation<SubPage1>();
            containerRegistry.RegisterForNavigation<SubPage2>();
        }
    }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SNMPでWIFIルーターの電波OFFをする

やりたいこと

WIFIルーターの電波on/offをリモートで行う。

前提となる知識

SNMP(Simple Network Management Protocol)

  • ネットワーク機器を管理するために用いられるプロトコル。今回でいうと、ルーターの設定値を読み出したり、電波をon/offしたり。
  • ルーターの設定をSNMPプロトコルを通じて変更が可能 (変更が許可されているもののみ)。
  • ルーターの設定値を読み出すことも可能。

MIBファイル形式

  • MIBファイルにはルーターの各設定について、OID(Object ID)が何で、データ型が何なのか、設定許可されているかどうかなどが記載されている。
  • ルーターの各設定項目について、それぞれObject ID(OID)が設定されている(メーカー独自)ため、ルーターのメーカーからMIBファイルを入手する必要がある。もしくはルーターの管理画面からダウンロードできるのかもしれない。
  • MIBファイル形式について
  • Q:SNMPv2形式の拡張MIBファイルの基本的な文法

OID(Object ID)について

設定値がツリー構造になっており、数字を順番に辿っていくと、ある設定値にたどり着く。たとえば、以下の例だとxxはベンダー名が割り当てられている。それ以降はモデル名だったり、設定値だったりと続いていく。これはベンダー毎に定義がされている。

1.3.6.1.4.1.xx

実際のMIBファイルはテキストになっているが、解読するのは結構大変だった。以下は実際の例。

使用したツール

TWSNMP

http://www.twise.co.jp/twsnmp.html

MIBファイルを読み込ませる必要がある。GUIで、設定値が一覧で見えてくるので直感的でわかりやすい。現在設定値の確認、ObjectIDの確認などを行うときに使用した。

snmpwalk (windowns)

コマンドラインで設定の読み出しや変更を行う。実際にプログラム内でコマンドを投げるときに、正しくObjectIDや型などを送信しないといけないのだが、そのコマンドの確認のために使用。TWSNMPだと、実際にどういうコマンドが投げられているのかはわからない。Object IDはわかるのだが、型をどう指定するのかとか、Object IDの末尾の数字をどうするとか、そのあたりが確認できた。

例えば、1.3.6.1.4.1.xx.xx.xx.xxというObject IDの値を読み出したいというとき、SNMPv2-SMI::なんとかと返ってくる。ちなみに-vはSNMPのバージョン(今回はv2)。 -cはコミュニティ名。ここでは"public"という名前(ルーターの設定でsnmp communityという項目があるはず)。1.3.6.1.4.1.xx.xx.xx.xxのあとに、1とか0などがでてきて、データ型がなんなのかを教えてくれる。で、実際にコマンドを投げるときは、1.3.6.1.4.1.xx.xx.xx.xx.1をObjectIDとする必要があった。ここがわからず結構はまった。

設定値の読み出し
c:\usr\bin>snmpwalk -v 2c -c public 192.168.1.10 1.3.6.1.4.1.xx.xx.xx.xx
SNMPv2-SMI::enterprises.xx.xx.xx.xx.1 = INTEGER:0
  • 設定の書き込みをする場合はルーターのsnmpの設定で、READ-WRITEの設定をしておく(書き込み可能にしておく)。
  • enterprises.xx.xx.xx.xx.1の最後に1なのか0なのかはMIBファイルを見ただけではわからなかった。(何か規則性がある?)
  • ここで得られたenterprises.xx.xx.xx.xx.1をOIDとして設定している。

SharpSnmp (.NET SNMP Library)

SNMPを行うためのライブラリ。いくつか似たようなのがある。

SNMP Library Documentation
インストール方法はここに書いてある。

using Lextm.SharpSnmpLib;
using Lextm.SharpSnmpLib.Messaging;
  • SNMPv2を使用した。v2はわりとシンプル。v3は認証などもありで複雑、たぶん。今回はローカルの環境でしか使用しないので、v2を使用。

SetRequest 設定を送信する

設定値の送信
private void SetRequest(string oid, int val)
        {
            // Snmp v2
            VersionCode version = VersionCode.V2;

            var receiver = new IPEndPoint(IPAddress.Parse(ip), snmpProt);
            Discovery discovery = Messenger.GetNextDiscovery(SnmpType.GetRequestPdu);
            ReportMessage report = discovery.GetResponse(timeout, receiver);

            // int型のデータを送信する場合
            ISnmpData data = new Integer32(val);

            // string型のデータを送信する場合
//            ISnmpData data = new OctetString(val);

            var test = new Variable(new ObjectIdentifier(oid), data);
            var vList = new List<Variable>();
            vList.Add(test);

            var request = new SetRequestMessage(Messenger.NextRequestId, version, new OctetString(community), vList);

            ISnmpMessage reply = request.GetResponse(timeout, receiver);

            if (reply.Pdu().ErrorStatus.ToInt32() != 0)
            {
                throw ErrorException.Create(
                    "error in response",
                    receiver.Address,
                    reply);
            }

            // 結果を出力
            foreach (Variable v in reply.Pdu().Variables)
            {
                Console.WriteLine(v);
            }
        }

設定を取得する

ここではint型の設定を返している。

設定値の取得
        private int GetRequest(string oid)
        {

            VersionCode version = VersionCode.V2;

            var receiver = new IPEndPoint(IPAddress.Parse(ip), snmpProt);
            Discovery discovery = Messenger.GetNextDiscovery(SnmpType.GetRequestPdu);
            ReportMessage report = discovery.GetResponse(timeout, receiver);

            // 取得したいOID
            var test = new Variable(new ObjectIdentifier(oid));
            var vList = new List<Variable>();
            vList.Add(test);

            var request = new GetRequestMessage(Messenger.NextRequestId, version, new OctetString(community), vList);

            ISnmpMessage reply = request.GetResponse(timeout, receiver);

            if (reply.Pdu().ErrorStatus.ToInt32() != 0)
            {
                throw ErrorException.Create(
                    "error in response",
                    receiver.Address,
                    reply);
            }

            // 結果を出力
            foreach (Variable v in reply.Pdu().Variables)
            {
                Console.WriteLine(v);                
            }

            return int.Parse(reply.Pdu().Variables[0].Data.ToString());
        }
    }

その他はまったポイント

ルーターの設定画面にラウザでアクセスしている状態(ログインしている)で、プログラムからコマンドを投げてもうまく反映がされなかった。コマンドを投げるときは、一旦ログアウトしてから、コマンドを投げる。その後、もう一度ルーターにログインして、値が変更されているかを確認する、といったことをやらなければならなかった。これも気づくまでに時間がかかった。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ReactiveProperty v7.2.0 をリリースしました

ReactiveProperty v7.2.0 をリリースしました。

NuGet パッケージはこちら

ReactiveProperty v7.2.0 | NuGet Gallery

追加

DisposePreviousValue 拡張メソッドが追加されています。
IObservable の最新より前の値に対して Dispose の呼び出しを行います。
ReadOnlyReactiveProperty<T> に対して Dispose の呼び出しが必要な型などを Select で生成して使う場合に便利です。

var source = new Subject<string>();

var rp = source.Select(x => new SomeDisposableObject(x))
    .DisposePreviousValue()
    .ToReadOnlyReactivePropertySlim();

source.OnNext("aaa");
source.OnNext("bbb"); // aaa から作られたものは Dispose される
source.OnComplete(); // ソースが終了したタイミングで現在の値も Dispose される
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

数独自動解法

導入

数独を自動で解くプログラムを作成した。
できるだけ早く、どんな問題も解くをコンセプトに設計開発をした。
自動生成部は説明割愛します。
肝となる Form1.cs について説明します。
複数関数で使う変数はグローバル変数で定義します。
関数呼び出しが長くなるし、ポインダーの定義が面倒だっだからです。
定数も、C#(VisualStado)ならではの定義方法となっています。
ファイル分けもしませんでした。グローバル変数を上手にとりまわせなかったのが原因です。
試行錯誤しながら作成したためソースが読みにくくなっています。

準備

81個のマスの数字を青色にします。

        public Form1()
        {
            InitializeComponent();
            BGamen();
        }

初期動作時に青色にしています。
BGamen();
が数字を青くする関数です。
Set_ColorB(textBox11);
で1つの枠の色を青くしています。

        //青くするのサブルーチン
        private void Set_ColorB(TextBox textBox)
        {
            textBox.ForeColor = Color.Blue;
        }

もう少しスマートな書き方もあっただろうがこれで目的を達成しています。
問題の数字を入力して、開始ボタンを押下すると0以外の数字を赤に変えて
計算処理開始です。
Gamen();
が数字を赤くする関数です。
Set_Color(textBox11);
で1つの枠の数字を赤くしています。

        //赤くするのサブルーチン
        private void Set_Color(TextBox textBox)
        {
            if( textBox.Text != "0")
            {
                textBox.ForeColor = Color.Red;
            }
        }

数字が0以外だったら文字を赤くしています。

計算

1.各枠に入る数字を初期化します。

                //各マスの設定できる数字の初期化
                for (int jj = 1; jj <= 9; jj++)
                {
                    for (int kk = 1; kk <= 9; kk++)
                    {
                        for (int ii = 0; ii <=9; ii++)
                        {
                            Num[ii, jj, kk] = 0;
                        }
                    }
                }

iiが縦位置、jjが横位置、kkが数字0は画面(1-9)が入る1-9は数字(あれば1、なければ0)このポリシーはプログラム全体に同じ。

2.各枠に入らない数字の洗い出し。
横方向にすでに数字があれば、kkの数字に1を立てる。
縦方向にすでに数字があれば、kkの数字に1を立てる。
隣り合った9升にすでに数字があれば、kkの数字に1を立てる。

3.kkが1-9の内1だけ0があればその数字をセットする。

4.3がなければ上の段の右から下の段の左に向かってkkの大きい数字の0をセット

5.矛盾が発生したら1個升を戻って1から実行

6.全升がうまったら終了

ちょっと長いけどソース。但しこれだけでは動きません。

/*
===============================================================================
数独ソリッドプログラム
解決力80%(予測)
タイムアタック及び解法手順確認用
オープンソース
基礎コーディング by N.Tanaka 2020.04.19
===============================================================================
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Threading;

//プロジェクト 数独表示
namespace SuudokuHyouji
{
    //メインフォームソース
    public partial class Form1 : Form
    {
        int[,,] No= new int[Con.CalcMax, 10, 10];   //メイン配列
        int[,,] Num = new int[10, 10, 10];          //各位置に書ける数字用配列
        Boolean FlgSet;                             //数字を新たにセット出来たか?
        Boolean Mujyun;                             //矛盾発生しているか?
        bool LoopFlg = true;                        //メインループ中?
        int Shin = 0;                               //手順位置
#if ERR101
        int[,] Ren = new int[2,3];                  //同一操作チェック用配列
#endif
        int[] Undo = new int[Con.CalcMax];          //操作を戻す用配列
        int[,] UBack = new int[Con.CalcMax,2];      //操作を戻す位置用配列
        int[,] NBack = new int[10, 2];              //太い線で囲まれた3×3の設定最初位置用配列
        int SShin = 0;                              //メイン配列書き込み位置
        int UShin;                                  //借置き位置
        int Back = 0;                               //現在の戻り位置
        int XBack = 0;                              //現在の位置の戻り数字
        int t = 0;                                  //時間計算用
#if DEBUG
        string log;
#endif

        public Form1()
        {
            InitializeComponent();
            BGamen();
        }

        //開始ボタン押下時の処理
        private void button1_Click(object sender, EventArgs e)
        {
            DateTime dt = DateTime.Now;             //開始時の現在時刻
            string result = dt.ToString();          //時刻の文字列
            int Rc;                                 //関数の戻り値

            //初期情報セット
            button1.Enabled = false;
            button2.Enabled = false;
            label1.Text += result;
            t = System.Environment.TickCount;

            get_No();
            Gamen();
            UBack[Shin, 0] = Back++;
            UBack[Shin, 1] = XBack++;

            //メインループ
            while (LoopFlg == true)
            {
                FlgSet = false;
                Mujyun = false;

                //各マスの設定できる数字の初期化
                for (int jj = 1; jj <= 9; jj++)
                {
                    for (int kk = 1; kk <= 9; kk++)
                    {
                        for (int ii = 0; ii <=9; ii++)
                        {
                            Num[ii, jj, kk] = 0;
                        }
                    }
                }

                //各マスの設定できる数字の算出
                for (int jj = 1; jj <= 9; jj++)
                {
                    for (int kk = 1; kk <= 9; kk++)
                    {
                        Tate_Set(No[Shin, jj, kk], kk);
                        Yoko_Set(No[Shin, jj, kk], jj);
                        A_Set(No[Shin, jj, kk], jj, kk);
                        B_Set(No[Shin, jj, kk], jj, kk);
                        C_Set(No[Shin, jj, kk], jj, kk);
                        D_Set(No[Shin, jj, kk], jj, kk);
                        E_Set(No[Shin, jj, kk], jj, kk);
                        F_Set(No[Shin, jj, kk], jj, kk);
                        G_Set(No[Shin, jj, kk], jj, kk);
                        H_Set(No[Shin, jj, kk], jj, kk);
                        I_Set(No[Shin, jj, kk], jj, kk);
                    }
                }

                // メッセージ・キューにあるWindowsメッセージをすべて処理する
                Application.DoEvents();

                //ただ1つの設定数字の確定
                for (int jj = 1; jj <= 9; jj++)
                {
                    for (int kk = 1; kk <= 9; kk++)
                    {
                        One_Kennsaku(jj, kk);
                        if (FlgSet == true) break;
                    }
                    if (FlgSet == true) break;
                }

                label3.Text = "思考:" + SShin.ToString();

                //解けた!!チェック
                if (Seikai() == 729) break;

                if (FlgSet == false)
                {
#if DEBUG
                    log = String.Concat("kuuhaku_Kennsaku\r\n");
                    LogSave(log);
#endif
                    //空白をチェックして埋める
                    kuuhaku_Kennsaku();
                    {
                        // メッセージ・キューにあるWindowsメッセージをすべて処理する
                        Application.DoEvents();
                    }

                    //解けた!!チェック
                    if (Seikai() == 729) break;

                }

                if (FlgSet == false)
                {
                    Undo[Shin] = 1;
#if DEBUG
                    log = String.Concat("Undo_kennsaku Shin =", Shin.ToString(), "\r\n");
                    LogSave(log);
#endif
                    //手順を戻す
                    if (Undo_kennsaku() == 0)
                    {
                        break;
                    }

                    //矛盾チェック
                    if (Mujyun == true)
                    {
                        Rc = Seikai();
                        if (Rc > 0) Rc = 0;
                        Go_Start(Rc);
                        if (FlgSet == false) break;
                        Mujyun = false;
                    }
                }

                Set_No();
                if (checkBox1.Checked == true) Thread.Sleep(200);

            }


            //解けなかった場合の処理
            if (Seikai() != 729)
            {
                 label2.Text = "降参";
            }

            Set_No();
            t = System.Environment.TickCount - t;
            int tHour = t / 1000 / 60 / 60;
            int tMinu = (t - tHour * 1000 * 60 * 60) / 1000 / 60;
            int tSec = (t - tHour * 1000 * 60 * 60 - tMinu * 1000 * 60) / 1000;
            int tmSec = t - tHour * 1000 * 60 * 60 - tMinu * 1000 * 60 - tSec * 1000;
            label2.Text += tHour.ToString() + "時" + tMinu.ToString() + "分" 
                + tSec.ToString() + "秒" + tmSec.ToString() + "ミリ秒";
            button2.Enabled = true;

        }

        //画面データ→配列データ
        private void get_No()
        {
             No[Shin, 1, 1] = int.Parse(textBox11.Text);
             No[Shin, 1, 2] = int.Parse(textBox12.Text);
             No[Shin, 1, 3] = int.Parse(textBox13.Text);
             No[Shin, 1, 4] = int.Parse(textBox14.Text);
             No[Shin, 1, 5] = int.Parse(textBox15.Text);
             No[Shin, 1, 6] = int.Parse(textBox16.Text);
             No[Shin, 1, 7] = int.Parse(textBox17.Text);
             No[Shin, 1, 8] = int.Parse(textBox18.Text);
             No[Shin, 1, 9] = int.Parse(textBox19.Text);

             No[Shin, 2, 1] = int.Parse(textBox21.Text);
             No[Shin, 2, 2] = int.Parse(textBox22.Text);
             No[Shin, 2, 3] = int.Parse(textBox23.Text);
             No[Shin, 2, 4] = int.Parse(textBox24.Text);
             No[Shin, 2, 5] = int.Parse(textBox25.Text);
             No[Shin, 2, 6] = int.Parse(textBox26.Text);
             No[Shin, 2, 7] = int.Parse(textBox27.Text);
             No[Shin, 2, 8] = int.Parse(textBox28.Text);
             No[Shin, 2, 9] = int.Parse(textBox29.Text);

             No[Shin, 3, 1] = int.Parse(textBox31.Text);
             No[Shin, 3, 2] = int.Parse(textBox32.Text);
             No[Shin, 3, 3] = int.Parse(textBox33.Text);
             No[Shin, 3, 4] = int.Parse(textBox34.Text);
             No[Shin, 3, 5] = int.Parse(textBox35.Text);
             No[Shin, 3, 6] = int.Parse(textBox36.Text);
             No[Shin, 3, 7] = int.Parse(textBox37.Text);
             No[Shin, 3, 8] = int.Parse(textBox38.Text);
             No[Shin, 3, 9] = int.Parse(textBox39.Text);

             No[Shin, 4, 1] = int.Parse(textBox41.Text);
             No[Shin, 4, 2] = int.Parse(textBox42.Text);
             No[Shin, 4, 3] = int.Parse(textBox43.Text);
             No[Shin, 4, 4] = int.Parse(textBox44.Text);
             No[Shin, 4, 5] = int.Parse(textBox45.Text);
             No[Shin, 4, 6] = int.Parse(textBox46.Text);
             No[Shin, 4, 7] = int.Parse(textBox47.Text);
             No[Shin, 4, 8] = int.Parse(textBox48.Text);
             No[Shin, 4, 9] = int.Parse(textBox49.Text);

             No[Shin, 5, 1] = int.Parse(textBox51.Text);
             No[Shin, 5, 2] = int.Parse(textBox52.Text);
             No[Shin, 5, 3] = int.Parse(textBox53.Text);
             No[Shin, 5, 4] = int.Parse(textBox54.Text);
             No[Shin, 5, 5] = int.Parse(textBox55.Text);
             No[Shin, 5, 6] = int.Parse(textBox56.Text);
             No[Shin, 5, 7] = int.Parse(textBox57.Text);
             No[Shin, 5, 8] = int.Parse(textBox58.Text);
             No[Shin, 5, 9] = int.Parse(textBox59.Text);

             No[Shin, 6, 1] = int.Parse(textBox61.Text);
             No[Shin, 6, 2] = int.Parse(textBox62.Text);
             No[Shin, 6, 3] = int.Parse(textBox63.Text);
             No[Shin, 6, 4] = int.Parse(textBox64.Text);
             No[Shin, 6, 5] = int.Parse(textBox65.Text);
             No[Shin, 6, 6] = int.Parse(textBox66.Text);
             No[Shin, 6, 7] = int.Parse(textBox67.Text);
             No[Shin, 6, 8] = int.Parse(textBox68.Text);
             No[Shin, 6, 9] = int.Parse(textBox69.Text);

             No[Shin, 7, 1] = int.Parse(textBox71.Text);
             No[Shin, 7, 2] = int.Parse(textBox72.Text);
             No[Shin, 7, 3] = int.Parse(textBox73.Text);
             No[Shin, 7, 4] = int.Parse(textBox74.Text);
             No[Shin, 7, 5] = int.Parse(textBox75.Text);
             No[Shin, 7, 6] = int.Parse(textBox76.Text);
             No[Shin, 7, 7] = int.Parse(textBox77.Text);
             No[Shin, 7, 8] = int.Parse(textBox78.Text);
             No[Shin, 7, 9] = int.Parse(textBox79.Text);

             No[Shin, 8, 1] = int.Parse(textBox81.Text);
             No[Shin, 8, 2] = int.Parse(textBox82.Text);
             No[Shin, 8, 3] = int.Parse(textBox83.Text);
             No[Shin, 8, 4] = int.Parse(textBox84.Text);
             No[Shin, 8, 5] = int.Parse(textBox85.Text);
             No[Shin, 8, 6] = int.Parse(textBox86.Text);
             No[Shin, 8, 7] = int.Parse(textBox87.Text);
             No[Shin, 8, 8] = int.Parse(textBox88.Text);
             No[Shin, 8, 9] = int.Parse(textBox89.Text);

             No[Shin, 9, 1] = int.Parse(textBox91.Text);
             No[Shin, 9, 2] = int.Parse(textBox92.Text);
             No[Shin, 9, 3] = int.Parse(textBox93.Text);
             No[Shin, 9, 4] = int.Parse(textBox94.Text);
             No[Shin, 9, 5] = int.Parse(textBox95.Text);
             No[Shin, 9, 6] = int.Parse(textBox96.Text);
             No[Shin, 9, 7] = int.Parse(textBox97.Text);
             No[Shin, 9, 8] = int.Parse(textBox98.Text);
             No[Shin, 9, 9] = int.Parse(textBox99.Text);

        }

        //配列データ→画面データ
        private void Set_No()
        {
            textBox11.Text =  No[Shin, 1, 1].ToString();
            textBox12.Text =  No[Shin, 1, 2].ToString();
            textBox13.Text =  No[Shin, 1, 3].ToString();
            textBox14.Text =  No[Shin, 1, 4].ToString();
            textBox15.Text =  No[Shin, 1, 5].ToString();
            textBox16.Text =  No[Shin, 1, 6].ToString();
            textBox17.Text =  No[Shin, 1, 7].ToString();
            textBox18.Text =  No[Shin, 1, 8].ToString();
            textBox19.Text =  No[Shin, 1, 9].ToString();

            textBox21.Text =  No[Shin, 2, 1].ToString();
            textBox22.Text =  No[Shin, 2, 2].ToString();
            textBox23.Text =  No[Shin, 2, 3].ToString();
            textBox24.Text =  No[Shin, 2, 4].ToString();
            textBox25.Text =  No[Shin, 2, 5].ToString();
            textBox26.Text =  No[Shin, 2, 6].ToString();
            textBox27.Text =  No[Shin, 2, 7].ToString();
            textBox28.Text =  No[Shin, 2, 8].ToString();
            textBox29.Text =  No[Shin, 2, 9].ToString();

            textBox31.Text =  No[Shin, 3, 1].ToString();
            textBox32.Text =  No[Shin, 3, 2].ToString();
            textBox33.Text =  No[Shin, 3, 3].ToString();
            textBox34.Text =  No[Shin, 3, 4].ToString();
            textBox35.Text =  No[Shin, 3, 5].ToString();
            textBox36.Text =  No[Shin, 3, 6].ToString();
            textBox37.Text =  No[Shin, 3, 7].ToString();
            textBox38.Text =  No[Shin, 3, 8].ToString();
            textBox39.Text =  No[Shin, 3, 9].ToString();

            textBox41.Text =  No[Shin, 4, 1].ToString();
            textBox42.Text =  No[Shin, 4, 2].ToString();
            textBox43.Text =  No[Shin, 4, 3].ToString();
            textBox44.Text =  No[Shin, 4, 4].ToString();
            textBox45.Text =  No[Shin, 4, 5].ToString();
            textBox46.Text =  No[Shin, 4, 6].ToString();
            textBox47.Text =  No[Shin, 4, 7].ToString();
            textBox48.Text =  No[Shin, 4, 8].ToString();
            textBox49.Text =  No[Shin, 4, 9].ToString();

            textBox51.Text =  No[Shin, 5, 1].ToString();
            textBox52.Text =  No[Shin, 5, 2].ToString();
            textBox53.Text =  No[Shin, 5, 3].ToString();
            textBox54.Text =  No[Shin, 5, 4].ToString();
            textBox55.Text =  No[Shin, 5, 5].ToString();
            textBox56.Text =  No[Shin, 5, 6].ToString();
            textBox57.Text =  No[Shin, 5, 7].ToString();
            textBox58.Text =  No[Shin, 5, 8].ToString();
            textBox59.Text =  No[Shin, 5, 9].ToString();

            textBox61.Text =  No[Shin, 6, 1].ToString();
            textBox62.Text =  No[Shin, 6, 2].ToString();
            textBox63.Text =  No[Shin, 6, 3].ToString();
            textBox64.Text =  No[Shin, 6, 4].ToString();
            textBox65.Text =  No[Shin, 6, 5].ToString();
            textBox66.Text =  No[Shin, 6, 6].ToString();
            textBox67.Text =  No[Shin, 6, 7].ToString();
            textBox68.Text =  No[Shin, 6, 8].ToString();
            textBox69.Text =  No[Shin, 6, 9].ToString();

            textBox71.Text =  No[Shin, 7, 1].ToString();
            textBox72.Text =  No[Shin, 7, 2].ToString();
            textBox73.Text =  No[Shin, 7, 3].ToString();
            textBox74.Text =  No[Shin, 7, 4].ToString();
            textBox75.Text =  No[Shin, 7, 5].ToString();
            textBox76.Text =  No[Shin, 7, 6].ToString();
            textBox77.Text =  No[Shin, 7, 7].ToString();
            textBox78.Text =  No[Shin, 7, 8].ToString();
            textBox79.Text =  No[Shin, 7, 9].ToString();

            textBox81.Text =  No[Shin, 8, 1].ToString();
            textBox82.Text =  No[Shin, 8, 2].ToString();
            textBox83.Text =  No[Shin, 8, 3].ToString();
            textBox84.Text =  No[Shin, 8, 4].ToString();
            textBox85.Text =  No[Shin, 8, 5].ToString();
            textBox86.Text =  No[Shin, 8, 6].ToString();
            textBox87.Text =  No[Shin, 8, 7].ToString();
            textBox88.Text =  No[Shin, 8, 8].ToString();
            textBox89.Text =  No[Shin, 8, 9].ToString();

            textBox91.Text =  No[Shin, 9, 1].ToString();
            textBox92.Text =  No[Shin, 9, 2].ToString();
            textBox93.Text =  No[Shin, 9, 3].ToString();
            textBox94.Text =  No[Shin, 9, 4].ToString();
            textBox95.Text =  No[Shin, 9, 5].ToString();
            textBox96.Text =  No[Shin, 9, 6].ToString();
            textBox97.Text =  No[Shin, 9, 7].ToString();
            textBox98.Text =  No[Shin, 9, 8].ToString();
            textBox99.Text =  No[Shin, 9, 9].ToString();

        }

        //最初入力数字を赤くする
        private void Gamen()
        {
            Set_Color(textBox11);
            Set_Color(textBox12);
            Set_Color(textBox13);
            Set_Color(textBox14);
            Set_Color(textBox15);
            Set_Color(textBox16);
            Set_Color(textBox17);
            Set_Color(textBox18);
            Set_Color(textBox19);

            Set_Color(textBox21);
            Set_Color(textBox22);
            Set_Color(textBox23);
            Set_Color(textBox24);
            Set_Color(textBox25);
            Set_Color(textBox26);
            Set_Color(textBox27);
            Set_Color(textBox28);
            Set_Color(textBox29);

            Set_Color(textBox31);
            Set_Color(textBox32);
            Set_Color(textBox33);
            Set_Color(textBox34);
            Set_Color(textBox35);
            Set_Color(textBox36);
            Set_Color(textBox37);
            Set_Color(textBox38);
            Set_Color(textBox39);

            Set_Color(textBox41);
            Set_Color(textBox42);
            Set_Color(textBox43);
            Set_Color(textBox44);
            Set_Color(textBox45);
            Set_Color(textBox46);
            Set_Color(textBox47);
            Set_Color(textBox48);
            Set_Color(textBox49);

            Set_Color(textBox51);
            Set_Color(textBox52);
            Set_Color(textBox53);
            Set_Color(textBox54);
            Set_Color(textBox55);
            Set_Color(textBox56);
            Set_Color(textBox57);
            Set_Color(textBox58);
            Set_Color(textBox59);

            Set_Color(textBox61);
            Set_Color(textBox62);
            Set_Color(textBox63);
            Set_Color(textBox64);
            Set_Color(textBox65);
            Set_Color(textBox66);
            Set_Color(textBox67);
            Set_Color(textBox68);
            Set_Color(textBox69);

            Set_Color(textBox71);
            Set_Color(textBox72);
            Set_Color(textBox73);
            Set_Color(textBox74);
            Set_Color(textBox75);
            Set_Color(textBox76);
            Set_Color(textBox77);
            Set_Color(textBox78);
            Set_Color(textBox79);

            Set_Color(textBox81);
            Set_Color(textBox82);
            Set_Color(textBox83);
            Set_Color(textBox84);
            Set_Color(textBox85);
            Set_Color(textBox86);
            Set_Color(textBox87);
            Set_Color(textBox88);
            Set_Color(textBox89);

            Set_Color(textBox91);
            Set_Color(textBox92);
            Set_Color(textBox93);
            Set_Color(textBox94);
            Set_Color(textBox95);
            Set_Color(textBox96);
            Set_Color(textBox97);
            Set_Color(textBox98);
            Set_Color(textBox99);

        }

        //赤くするのサブルーチン
        private void Set_Color(TextBox textBox)
        {
            if( textBox.Text != "0")
            {
                textBox.ForeColor = Color.Red;
            }
        }

        //最初入力数字を青くする
        private void BGamen()
        {
            Set_ColorB(textBox11);
            Set_ColorB(textBox12);
            Set_ColorB(textBox13);
            Set_ColorB(textBox14);
            Set_ColorB(textBox15);
            Set_ColorB(textBox16);
            Set_ColorB(textBox17);
            Set_ColorB(textBox18);
            Set_ColorB(textBox19);

            Set_ColorB(textBox21);
            Set_ColorB(textBox22);
            Set_ColorB(textBox23);
            Set_ColorB(textBox24);
            Set_ColorB(textBox25);
            Set_ColorB(textBox26);
            Set_ColorB(textBox27);
            Set_ColorB(textBox28);
            Set_ColorB(textBox29);

            Set_ColorB(textBox31);
            Set_ColorB(textBox32);
            Set_ColorB(textBox33);
            Set_ColorB(textBox34);
            Set_ColorB(textBox35);
            Set_ColorB(textBox36);
            Set_ColorB(textBox37);
            Set_ColorB(textBox38);
            Set_ColorB(textBox39);

            Set_ColorB(textBox41);
            Set_ColorB(textBox42);
            Set_ColorB(textBox43);
            Set_ColorB(textBox44);
            Set_ColorB(textBox45);
            Set_ColorB(textBox46);
            Set_ColorB(textBox47);
            Set_ColorB(textBox48);
            Set_ColorB(textBox49);

            Set_ColorB(textBox51);
            Set_ColorB(textBox52);
            Set_ColorB(textBox53);
            Set_ColorB(textBox54);
            Set_ColorB(textBox55);
            Set_ColorB(textBox56);
            Set_ColorB(textBox57);
            Set_ColorB(textBox58);
            Set_ColorB(textBox59);

            Set_ColorB(textBox61);
            Set_ColorB(textBox62);
            Set_ColorB(textBox63);
            Set_ColorB(textBox64);
            Set_ColorB(textBox65);
            Set_ColorB(textBox66);
            Set_ColorB(textBox67);
            Set_ColorB(textBox68);
            Set_ColorB(textBox69);

            Set_ColorB(textBox71);
            Set_ColorB(textBox72);
            Set_ColorB(textBox73);
            Set_ColorB(textBox74);
            Set_ColorB(textBox75);
            Set_ColorB(textBox76);
            Set_ColorB(textBox77);
            Set_ColorB(textBox78);
            Set_ColorB(textBox79);

            Set_ColorB(textBox81);
            Set_ColorB(textBox82);
            Set_ColorB(textBox83);
            Set_ColorB(textBox84);
            Set_ColorB(textBox85);
            Set_ColorB(textBox86);
            Set_ColorB(textBox87);
            Set_ColorB(textBox88);
            Set_ColorB(textBox89);

            Set_ColorB(textBox91);
            Set_ColorB(textBox92);
            Set_ColorB(textBox93);
            Set_ColorB(textBox94);
            Set_ColorB(textBox95);
            Set_ColorB(textBox96);
            Set_ColorB(textBox97);
            Set_ColorB(textBox98);
            Set_ColorB(textBox99);

        }

        //青くするのサブルーチン
        private void Set_ColorB(TextBox textBox)
        {
            textBox.ForeColor = Color.Blue;
        }

        //縦使用数値設定
        private void Tate_Set(int mm, int j)
        {
            if(mm == 0)
            {
                return;
            }

            for ( int i = 1; i <= 9; i++ )
            {
                 Num[mm, i, j] = 1;
            }

            return;
        }

        //横使用数値設定
        private void Yoko_Set(int mm, int j)
        {
            if (mm == 0)
            {
                return;
            }

            for (int i = 1; i <= 9; i++)
            {
                Num[mm, j, i] = 1;
            }

            return;

        }

        private void A_Set(int mm, int kk, int jj)
        {
            int[,] gloup = new int[9, 2] { { 1, 1 }, { 1, 2 }, { 1, 3 }, 
                                            { 2, 1 }, { 2, 2 }, { 2, 3 }, 
                                            { 3, 1 }, { 3, 2 }, { 3, 3 } };

            if (mm == 0)
            {
                return;
            }

            if(kk > 3 || jj > 3 )
            {
                return;
            }

            for (int i = 0; i <= 8; i++)
            {
                Num[mm, gloup[i, 0], gloup[i, 1]] = 1;
            }

            return;
        }

        private void B_Set(int mm, int kk, int jj)
        {
            int[,] gloup = new int[9, 2] { { 1, 4 }, { 1, 5 }, { 1, 6 },
                                            { 2, 4 }, { 2, 5 }, { 2, 6 },
                                            { 3, 4 }, { 3, 5 }, { 3, 6 } };

            if (mm == 0)
            {
                return;
            }

            if (kk > 3 || jj < 4 || jj > 6)
            {
                return;
            }

            for (int i = 0; i <= 8; i++)
            {
                Num[mm, gloup[i, 0], gloup[i, 1]] = 1;
            }

            return;
        }

        private void C_Set(int mm, int kk, int jj)
        {
            int[,] gloup = new int[9, 2] { { 1, 7 }, { 1, 8 }, { 1, 9 },
                                            { 2, 7 }, { 2, 8 }, { 2, 9 },
                                            { 3, 7 }, { 3, 8 }, { 3, 9 } };

            if (mm == 0)
            {
                return;
            }

            if (kk > 3 || jj < 7)
            {
                return;
            }

            for (int i = 0; i <= 8; i++)
            {
                Num[mm, gloup[i, 0], gloup[i, 1]] = 1;
            }

            return;
        }

        private void D_Set(int mm, int kk, int jj)
        {
            int[,] gloup = new int[9, 2] { { 4, 1 }, { 4, 2 }, { 4, 3 }, 
                                            { 5, 1 }, { 5, 2 }, { 5, 3 }, 
                                            { 6, 1 }, { 6, 2 }, { 6, 3 } };

            if (mm == 0)
            {
                return;
            }

            if (kk < 4 || kk > 6 || jj > 3)
            {
                return;
            }

            for (int i = 0; i <= 8; i++)
            {
                Num[mm, gloup[i, 0], gloup[i, 1]] = 1;
            }

            return;
        }

        private void E_Set(int mm, int kk, int jj)
        {
            int[,] gloup = new int[9, 2] { { 4, 4 }, { 4, 5 }, { 4, 6 },
                                            { 5, 4 }, { 5, 5 }, { 5, 6 },
                                            { 6, 4 }, { 6, 5 }, { 6, 6 } };

            if (mm == 0)
            {
                return;
            }

            if (kk < 4 || kk > 6 || jj < 4 || jj > 6)
            {
                return;
            }

            for (int i = 0; i <= 8; i++)
            {
                Num[mm, gloup[i, 0], gloup[i, 1]] = 1;
            }

            return;
        }

        private void F_Set(int mm, int kk, int jj)
        {
            int[,] gloup = new int[9, 2] { { 4, 7 }, { 4, 8 }, { 4, 9 },
                                            { 5, 7 }, { 5, 8 }, { 5, 9 },
                                            { 6, 7 }, { 6, 8 }, { 6, 9 } };

            if (mm == 0)
            {
                return;
            }

            if (kk < 4 || kk > 6 || jj < 7)
            {
                return;
            }

            for (int i = 0; i <= 8; i++)
            {
                Num[mm, gloup[i, 0], gloup[i, 1]] = 1;
            }

            return;
        }

        private void G_Set(int mm, int kk, int jj)
        {
            int[,] gloup = new int[9, 2] { { 7, 1 }, { 7, 2 }, { 7, 3 }, 
                                            { 8, 1 }, { 8, 2 }, { 8, 3 }, 
                                            { 9, 1 }, { 9, 2 }, { 9, 3 } };

            if (mm == 0)
            {
                return;
            }

            if (kk < 7  || jj > 3)
            {
                return;
            }

            for (int i = 0; i <= 8; i++)
            {
                Num[mm, gloup[i, 0], gloup[i, 1]] = 1;
            }

            return;
        }
        private void H_Set(int mm, int kk, int jj)
        {
            int[,] gloup = new int[9, 2] { { 7, 4 }, { 7, 5 }, { 7, 6 }, 
                                            { 8, 4 }, { 8, 5 }, { 8, 6 }, 
                                            { 9, 4 }, { 9, 5 }, { 9, 6 } };

            if (mm == 0)
            {
                return;
            }

            if (kk < 7 || jj < 4 || jj > 6)
            {
                return;
            }

            for (int i = 0; i <= 8; i++)
            {
                Num[mm, gloup[i, 0], gloup[i, 1]] = 1;
            }

            return;
        }
        private void I_Set(int mm, int kk, int jj)
        {
            int[,] gloup = new int[9, 2] { { 7, 7 }, { 7, 8 }, { 7, 9 }, 
                                            { 8, 7 }, { 8, 8 }, { 8, 9 }, 
                                            { 9, 7 }, { 9, 8 }, { 9, 9 } };

            if (mm == 0)
            {
                return;
            }

            if (kk < 7 || jj < 7)
            {
                return;
            }

            for (int i = 0; i <= 8; i++)
            {
                Num[mm, gloup[i, 0], gloup[i, 1]] = 1;
            }

            return;
        }

        //確定数値1個の決定
        private void One_Kennsaku(int jj, int kk)
        {
            int Cnt = 0;
            int work = 0;

            if ( No[Shin, jj, kk] != 0)
            {
                return;
            }

            for (int i = 1; i <= 9; i++)
            {
                if ( Num[i, jj, kk] == 0)
                {
                    Cnt++;
                    work = i;
                }
            }

            if (Cnt == 1)
            {
                No[Shin, jj, kk] = work;
                FlgSet = true;
#if DEBUG
                log = String.Concat("One_Kennsaku jj = ", jj.ToString());
                LogSave(log);
                log = String.Concat(" kk = ", kk.ToString());
                LogSave(log);
                log = String.Concat(" work = ", work.ToString(), "\r\n");
                LogSave(log);
#endif
            }

                return;
        }

        //空白検索
        private int kuuhaku_Kennsaku()
        {
            int rc = 0;
            int Cnt;
            int SetCnt = 0;
            Boolean UFlag = false;
            Boolean USet = false;
            int[] work = new int [10];

            for (int jj = 1; jj <= 9; jj++)
            {
                for (int kk = 1; kk <= 9; kk++)
                {
                    if (No[Shin, jj, kk] != 0)
                    {
                        SetCnt++;
                        if (SetCnt >= 81)
                        {
                            FlgSet = true;
                            return rc;
                        }
                        continue;
                    }

                    Cnt = 0;
                    for (int i = 1; i <= 9; i++)
                    {
                        if (Num[i, jj, kk] == 0)
                        {
                            work[Cnt++] = i;
                        }
                    }

                    if (Cnt == 0)
                    {
                        UFlag = true;
                        break;
                    }

#if ERR101
                    if (Ren[0,0] == 0)
                    {
                        Ren[0, 0] = 1;
                        Ren[0, 1] = jj;
                        Ren[0, 2] = kk;
                    }
                    else
                    {
                        if (Ren[1,0] == 1)
                        {
                            Ren[0, 1] = Ren[1, 1];
                            Ren[0, 2] = Ren[1, 2];
                        }
                        Ren[1, 0] = 1;
                        Ren[1, 1] = jj;
                        Ren[1, 2] = kk;
                        if (Ren[0, 1] == Ren[1, 1] && Ren[0, 2] == Ren[1, 2])
                        {
                            UFlag = true;
                            break;
                        }
                    }
#endif
                    for (int rr = 0; rr < Cnt; rr++)
                    {
                        if (SShin + 1 >= Con.CalcMax)
                        {
                            FlgSet = false;
                            return rc;
                        }

                        CopyMap(SShin + 1, Shin);
                        No[SShin + 1, jj, kk] = work[rr];
                        UBack[SShin + 1, 0] = Back;
                        UBack[SShin + 1, 1] = XBack;
                        SShin++;
#if DEBUG
                        log = String.Concat("kuuhaku_Kennsaku loop SShin = ", SShin.ToString());
                        LogSave(log);
                        log = String.Concat(" jj = ", jj.ToString());
                        LogSave(log);
                        log = String.Concat(" kk = ", kk.ToString());
                        LogSave(log);
                        log = String.Concat(" work[rr] = ", work[rr].ToString());
                        LogSave(log);
                        log = String.Concat(" UBack[SShin+1, 0] Back= ", Back.ToString());
                        LogSave(log);
                        log = String.Concat(" UBack[SShin+1, 1] XBack= ", XBack.ToString(), "\r\n");
                        LogSave(log);
#endif
                        USet = true;
                    }

                    if ( USet == true)
                    {
                        {
                            int[,] gloup = new int[9, 2] { { 1, 1 }, { 1, 2 }, { 1, 3 },
                                            { 2, 1 }, { 2, 2 }, { 2, 3 },
                                            { 3, 1 }, { 3, 2 }, { 3, 3 } };
                            bool SSFlg = false;
                            for (int i = 0; i <= 8; i++)
                            {
                                if (jj == gloup[i, 0] && kk == gloup[i, 1]) SSFlg = true;
                            }
                            if (Shin > 0 && SSFlg == true && NBack[1, 0] == 0)
                            {
                                NBack[1, 0] = 1;
                                NBack[1, 1] = SShin;
                            }
                        }

                        {
                            int[,] gloup = new int[9, 2] { { 1, 4 }, { 1, 5 }, { 1, 6 },
                                            { 2, 4 }, { 2, 5 }, { 2, 6 },
                                            { 3, 4 }, { 3, 5 }, { 3, 6 } };
                            bool SSFlg = false;
                            for (int i = 0; i <= 8; i++)
                            {
                                if (jj == gloup[i, 0] && kk == gloup[i, 1]) SSFlg = true;
                            }
                            if (Shin > 0 && SSFlg == true && NBack[2, 0] == 0)
                            {
                                NBack[2, 0] = 1;
                                NBack[2, 1] = SShin;
                            }
                        }

                        {
                            int[,] gloup = new int[9, 2] { { 1, 7 }, { 1, 8 }, { 1, 9 },
                                            { 2, 7 }, { 2, 8 }, { 2, 9 },
                                            { 3, 7 }, { 3, 8 }, { 3, 9 } };
                            bool SSFlg = false;
                            for (int i = 0; i <= 8; i++)
                            {
                                if (jj == gloup[i, 0] && kk == gloup[i, 1]) SSFlg = true;
                            }
                            if (Shin > 0 && SSFlg == true && NBack[3, 0] == 0)
                            {
                                NBack[3, 0] = 1;
                                NBack[3, 1] = SShin;
                            }
                        }

                        {
                            int[,] gloup = new int[9, 2] { { 4, 1 }, { 4, 2 }, { 4, 3 },
                                            { 5, 1 }, { 5, 2 }, { 5, 3 },
                                            { 6, 1 }, { 6, 2 }, { 6, 3 } };
                            bool SSFlg = false;
                            for (int i = 0; i <= 8; i++)
                            {
                                if (jj == gloup[i, 0] && kk == gloup[i, 1]) SSFlg = true;
                            }
                            if (Shin > 0 && SSFlg == true && NBack[4, 0] == 0)
                            {
                                NBack[4, 0] = 1;
                                NBack[4, 1] = SShin;
                            }
                        }

                        {
                            int[,] gloup = new int[9, 2] { { 4, 4 }, { 4, 5 }, { 4, 6 },
                                            { 5, 4 }, { 5, 5 }, { 5, 6 },
                                            { 6, 4 }, { 6, 5 }, { 6, 6 } };
                            bool SSFlg = false;
                            for (int i = 0; i <= 8; i++)
                            {
                                if (jj == gloup[i, 0] && kk == gloup[i, 1]) SSFlg = true;
                            }
                            if (Shin > 0 && SSFlg == true && NBack[5, 0] == 0)
                            {
                                NBack[5, 0] = 1;
                                NBack[5, 1] = SShin;
                            }
                        }

                        {
                            int[,] gloup = new int[9, 2] { { 4, 7 }, { 4, 8 }, { 4, 9 },
                                            { 5, 7 }, { 5, 8 }, { 5, 9 },
                                            { 6, 7 }, { 6, 8 }, { 6, 9 } };
                            bool SSFlg = false;
                            for (int i = 0; i <= 8; i++)
                            {
                                if (jj == gloup[i, 0] && kk == gloup[i, 1]) SSFlg = true;
                            }
                            if (Shin > 0 && SSFlg == true && NBack[6, 0] == 0)
                            {
                                NBack[6, 0] = 1;
                                NBack[6, 1] = SShin;
                            }
                        }

                        {
                            int[,] gloup = new int[9, 2] { { 7, 1 }, { 7, 2 }, { 7, 3 },
                                            { 8, 1 }, { 8, 2 }, { 8, 3 },
                                            { 9, 1 }, { 9, 2 }, { 9, 3 } };
                            bool SSFlg = false;
                            for (int i = 0; i <= 8; i++)
                            {
                                if (jj == gloup[i, 0] && kk == gloup[i, 1]) SSFlg = true;
                            }
                            if (Shin > 0 && SSFlg == true && NBack[7, 0] == 0)
                            {
                                NBack[7, 0] = 1;
                                NBack[7, 1] = SShin;
                            }
                        }

                        {
                            int[,] gloup = new int[9, 2] { { 7, 4 }, { 7, 5 }, { 7, 6 },
                                            { 8, 4 }, { 8, 5 }, { 8, 6 },
                                            { 9, 4 }, { 9, 5 }, { 9, 6 } };
                            bool SSFlg = false;
                            for (int i = 0; i <= 8; i++)
                            {
                                if (jj == gloup[i, 0] && kk == gloup[i, 1]) SSFlg = true;
                            }
                            if (Shin > 0 && SSFlg == true && NBack[8, 0] == 0)
                            {
                                NBack[8, 0] = 1;
                                NBack[8, 1] = SShin;
                            }
                        }

                        {
                            int[,] gloup = new int[9, 2] { { 7, 7 }, { 7, 8 }, { 7, 9 },
                                            { 8, 7 }, { 8, 8 }, { 8, 9 },
                                            { 9, 7 }, { 9, 8 }, { 9, 9 } };
                            bool SSFlg = false;
                            for (int i = 0; i <= 8; i++)
                            {
                                if (jj == gloup[i, 0] && kk == gloup[i, 1]) SSFlg = true;
                            }
                            if (Shin > 0 && SSFlg == true && NBack[9, 0] == 0)
                            {
                                NBack[9, 0] = 1;
                                NBack[9, 1] = SShin;
                            }
                        }

                        Back = SShin;
                        XBack++;
                        break;
                    }
                }

                if (USet == true || UFlag == true)
                {
                    break;
                }

            }

            if ( UFlag == true)
            {
                FlgSet = false;
                Undo[Shin] = 1;
            } 
            else
            {
                FlgSet = true;
            }

            if (USet == false && UFlag == false)
            {
                Mujyun = true;
            }

            Shin = SShin;

            return rc;
        }

        //正解チェック
        private int Seikai()
        {
            int Rc = 0;

            UShin = Shin;

            for (int jj = 1; jj <= 9; jj++)
            {
                for (int kk = 1; kk <= 9; kk++)
                {
                    for (int nn = 1; nn <=9; nn++)
                    {
                        int[] ss = new int[11] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

                        ss[0] = A_UNum(nn, jj, kk);
                        ss[1] = B_UNum(nn, jj, kk);
                        ss[2] = C_UNum(nn, jj, kk);
                        ss[3] = D_UNum(nn, jj, kk);
                        ss[4] = E_UNum(nn, jj, kk);
                        ss[5] = F_UNum(nn, jj, kk);
                        ss[6] = G_UNum(nn, jj, kk);
                        ss[7] = H_UNum(nn, jj, kk);
                        ss[8] = I_UNum(nn, jj, kk);

                        for (int mm = 0; mm <= 8; mm++)
                        {
                            if (ss[mm] == 1)
                            {
                                Rc++;
                            }
                            else if (ss[mm] > 0)
                            {
                                Rc = (mm + 1) * -100;
#if DEBUG
                                log = String.Concat("Seikai loop mm = ", mm.ToString());
                                LogSave(log);
                                log = String.Concat(" ss[mm] = ", ss[mm].ToString());
                                LogSave(log);
                                log = String.Concat(" Shin = ", Shin.ToString());
                                LogSave(log);
                                log = String.Concat(" UShin = ", UShin.ToString(), "\r\n");
                                LogSave(log);
#endif
                                Go_Start(Rc);
                                return Rc;
                            }
                        }

                    }

                }

            }

            return Rc;
        }


        private int Tate_UNum(int mm, int j)
        {
            int rc = 0;

            if (mm == 0)
            {
                return rc;
            }

            for (int i = 1; i <= 9; i++)
            {
                if (No[UShin, i, j] == mm)
                {
                    rc++;
                }
            }

            return rc;
        }

        private int Yoko_UNum(int mm, int j)
        {
            int rc = 0;

            if (mm == 0)
            {
                return rc;
            }

            for (int i = 1; i <= 9; i++)
            {
                if (No[UShin, j, i] == mm)
                {
                    rc++;
                }
            }

            return rc;

        }

        private int A_UNum(int mm, int kk, int jj)
        {
            int rc = 0;
            int[,] gloup = new int[9, 2] { { 1, 1 }, { 1, 2 }, { 1, 3 }, 
                                            { 2, 1 }, { 2, 2 }, { 2, 3 }, 
                                            { 3, 1 }, { 3, 2 }, { 3, 3 } };

            if (mm == 0)
            {
                return rc;
            }

            if (kk > 3 || jj > 3)
            {
                return rc;
            }

            for (int i = 0; i <= 8; i++)
            {
                if (No[UShin, gloup[i, 0], gloup[i, 1]] == mm)
                {
                    rc++;
                }
            }

            return rc;
        }

        private int B_UNum(int mm, int kk, int jj)
        {
            int rc = 0;
            int[,] gloup = new int[9, 2] { { 1, 4 }, { 1, 5 }, { 1, 6 },
                                            { 2, 4 }, { 2, 5 }, { 2, 6 },
                                            { 3, 4 }, { 3, 5 }, { 3, 6 } };

            if (mm == 0)
            {
                return rc;
            }

            if (kk > 3 || jj < 4 || jj > 6)
            {
                return rc;
            }

            for (int i = 0; i <= 8; i++)
            {
                if (No[UShin, gloup[i, 0], gloup[i, 1]] == mm)
                {
                    rc++;
                }
            }

            return rc;
        }

        private int C_UNum(int mm, int kk, int jj)
        {
            int rc = 0;
            int[,] gloup = new int[9, 2] { { 1, 7 }, { 1, 8 }, { 1, 9 },
                                            { 2, 7 }, { 2, 8 }, { 2, 9 },
                                            { 3, 7 }, { 3, 8 }, { 3, 9 } };

            if (mm == 0)
            {
                return rc;
            }

            if (kk > 3 || jj < 7)
            {
                return rc;
            }

            for (int i = 0; i <= 8; i++)
            {
                if (No[UShin, gloup[i, 0], gloup[i, 1]] == mm)
                {
                    rc++;
                }
            }

            return rc;
        }

        private int D_UNum(int mm, int kk, int jj)
        {
            int rc = 0;
            int[,] gloup = new int[9, 2] { { 4, 1 }, { 4, 2 }, { 4, 3 }, 
                                            { 5, 1 }, { 5, 2 }, { 5, 3 }, 
                                            { 6, 1 }, { 6, 2 }, { 6, 3 } };

            if (mm == 0)
            {
                return rc;
            }

            if (kk < 4 || kk > 6 || jj > 3)
            {
                return rc;
            }

            for (int i = 0; i <= 8; i++)
            {
                if (No[UShin, gloup[i, 0], gloup[i, 1]] == mm)
                {
                    rc++;
                }
            }

            return rc;
        }

        private int E_UNum(int mm, int kk, int jj)
        {
            int rc = 0;
            int[,] gloup = new int[9, 2] { { 4, 4 }, { 4, 5 }, { 4, 6 },
                                            { 5, 4 }, { 5, 5 }, { 5, 6 },
                                            { 6, 4 }, { 6, 5 }, { 6, 6 } };

            if (mm == 0)
            {
                return rc;
            }

            if (kk < 4 || kk > 6 || jj < 4 || jj > 6)
            {
                return rc;
            }

            for (int i = 0; i <= 8; i++)
            {
                if (No[UShin, gloup[i, 0], gloup[i, 1]] == mm)
                {
                    rc++;
                }
            }

            return rc;
        }

        private int F_UNum(int mm, int kk, int jj)
        {
            int rc = 0;
            int[,] gloup = new int[9, 2] { { 4, 7 }, { 4, 8 }, { 4, 9 },
                                            { 5, 7 }, { 5, 8 }, { 5, 9 },
                                            { 6, 7 }, { 6, 8 }, { 6, 9 } };

            if (mm == 0)
            {
                return rc;
            }

            if (kk < 4 || kk > 6 || jj < 7)
            {
                return rc;
            }

            for (int i = 0; i <= 8; i++)
            {
                if (No[UShin, gloup[i, 0], gloup[i, 1]] == mm)
                {
                    rc++;
                }
            }

            return rc;
        }

        private int G_UNum(int mm, int kk, int jj)
        {
            int rc = 0;
            int[,] gloup = new int[9, 2] { { 7, 1 }, { 7, 2 }, { 7, 3 },
                                            { 8, 1 }, { 8, 2 }, { 8, 3 }, 
                                            { 9, 1 }, { 9, 2 }, { 9, 3 } };

            if (mm == 0)
            {
                return rc;
            }

            if (kk < 7 || jj > 3)
            {
                return rc;
            }

            for (int i = 0; i <= 8; i++)
            {
                if (No[UShin, gloup[i, 0], gloup[i, 1]] == mm)
                {
                    rc++;
                }
            }

            return rc;
        }

        private int H_UNum(int mm, int kk, int jj)
        {
            int rc = 0;
            int[,] gloup = new int[9, 2] { { 7, 4 }, { 7, 5 }, { 7, 6 }, 
                                            { 8, 4 }, { 8, 5 }, { 8, 6 }, 
                                            { 9, 4 }, { 9, 5 }, { 9, 6 } };

            if (mm == 0)
            {
                return rc;
            }

            if (kk < 7 || jj < 4 || jj > 6)
            {
                return rc;
            }

            for (int i = 0; i <= 8; i++)
            {
                if (No[UShin, gloup[i, 0], gloup[i, 1]] == mm)
                {
                    rc++;
                }
            }

            return rc;
        }

        private int I_UNum(int mm, int kk, int jj)
        {
            int rc = 0;
            int[,] gloup = new int[9, 2] { { 7, 7 }, { 7, 8 }, { 7, 9 }, 
                                            { 8, 7 }, { 8, 8 }, { 8, 9 }, 
                                            { 9, 7 }, { 9, 8 }, { 9, 9 } };

            if (mm == 0)
            {
                return rc;
            }

            if (kk < 7 || jj < 7)
            {
                return rc;
            }

            for (int i = 0; i <= 8; i++)
            {
                if (No[UShin, gloup[i, 0], gloup[i, 1]] == mm)
                {
                    rc++;
                }
            }

            return rc;
        }

        //思考画面を戻す
        private int Undo_kennsaku()
        {
            int Rc = 0;

            for (int i = Shin; i >= 1; i--)
            {
                if (Undo[i] == 0)
                {
                    Rc = i;
                    break;
                }
            }

            if ( Rc != 0)
            {
                Undo[Rc] = 1;

#if DEBUG
                log = String.Concat("  Rc =", Rc.ToString(), "\r\n");
                LogSave(log);
#endif
                Shin = Rc;
            }

            return Rc;
        }

        //画面コピー
        private void CopyMap(int t1, int t2)
        {
            for (int j2 = 1; j2 <= 9; j2++)
            {
                for (int j3 = 1; j3 <= 9; j3++)
                {
                    No[t1, j2, j3] = No[t2, j2, j3];
                }

            }
        }

        //最初の分岐まで戻す
        private void Go_Start(int TT)
        {
            int Rc = 0;
            int WW = 0;
            FlgSet = true;

#if DEBUG
            log = String.Concat("Go_Start TT = ", TT.ToString(), "\r\n");
            LogSave(log);
#endif
            switch (TT)
            {
                case 0:
                    for(int i = 1; i <= 9; i++)
                    {
                        if (NBack[i, 0] == 1)
                        {
                            WW = UBack[NBack[i, 1], 1];
#if DEBUG
                            log = String.Concat("Go_Start i = ", i.ToString());
                            LogSave(log);
                            log = String.Concat(" NBack[i, 1] = ", NBack[i, 1].ToString(), "\r\n");
                            LogSave(log);
#endif
                            break;
                        }
                    }
                    break;
                case -100:
                    WW = UBack[NBack[1, 1], 1];
                    break;
                case -200:
                    WW = UBack[NBack[2, 1], 1];
                    break;
                case -300:
                    WW = UBack[NBack[3, 1], 1];
                    break;
                case -400:
                    WW = UBack[NBack[4, 1], 1];
                    break;
                case -500:
                    WW = UBack[NBack[5, 1], 1];
                    break;
                case -600:
                    WW = UBack[NBack[6, 1], 1];
                    break;
                case -700:
                    WW = UBack[NBack[7, 1], 1];
                    break;
                case -800:
                    WW = UBack[NBack[8, 1], 1];
                    break;
                case -900:
                    WW = UBack[NBack[9, 1], 1];
                    break;
                default:
                    FlgSet = false;
                    return;
            }

#if DEBUG
            log = String.Concat("Go_Start Shin = ", Shin.ToString());
            LogSave(log);
            log = String.Concat(" WW = ", WW.ToString(), "\r\n");
            LogSave(log);
#endif
            if (WW == 0)
            {
                LoopFlg = false;
                return;
            }
            for (int i = Shin; i >= 1; i--)
            {
                if (Undo[i] == 0 && UBack[i,1] == WW)
                {
                    Shin = UBack[i, 0];
                    Undo[Shin] = 1;
                    Rc = i;
                    break;
                }
            }

            if ( Rc != 0)
            {
                for (int i = Shin; i >= 1; i--)
                {
                    if (Undo[i] == 0 && UBack[i, 1] == WW)
                    {
                        Shin = i;
                        Back = i;
                        Rc = i;
                        Undo[Rc] = 1;
                        if (SShin + 1 >= Con.CalcMax)
                        {
                            FlgSet = false;
                            return;
                        }

                        if (UBack[NBack[1, 1], 0] == 1 && UBack[i, 1] == UBack[NBack[1, 1], 1])
                        {
                            for (int k = 0; k <= 9; k++)
                            {
                                NBack[k, 0] = 0;
                                NBack[k, 1] = 0;
                            }

                        }
                        CopyMap(SShin + 1, Rc);
                        Shin = SShin + 1;
                        SShin++;
                        UBack[Shin, 0] = Shin;
                        UBack[Shin, 1] = XBack++;
                        break;
                    }
                    else
                    {
                        if (UBack[i, 1] != WW)
                        {
                            FlgSet = false;
                            for (int j = 1; j <= 9; j++)
                            {
                                if (Undo[i] == 0 && NBack[j, 0] == 1)
                                {
                                    Undo[i] = 1;
                                    WW = UBack[NBack[j, 1], 1];
                                    FlgSet = true;
                                    if (SShin + 1 >= Con.CalcMax)
                                    {
                                        FlgSet = false;
                                        return;
                                    }

                                    CopyMap(SShin + 1, i);
                                    Shin = SShin + 1;
                                    SShin++;
                                    UBack[Shin, 0] = Shin;
                                    UBack[Shin, 1] = XBack++;
#if DEBUG
                                    log = String.Concat("Go_Start Shin = ", Shin.ToString());
                                    LogSave(log);
                                    log = String.Concat(" j = ", j.ToString());
                                    LogSave(log);
                                    log = String.Concat(" NBack[j, 1] = ", NBack[j, 1].ToString(), "\r\n");
                                    LogSave(log);
#endif
                                    return;
                                }
                            }
                        } 
                        else
                        {
                            Rc = 0;
                            LoopFlg = false;
                            return;
                        }
                    }
                }

            }

            if (Rc == 0)
            {
                FlgSet = false;
                return; 
            }

        }

        private void LogSave(string text)
        {
            string filePath = @"Debag.log";

            StreamWriter sw = new StreamWriter(filePath, true, Encoding.GetEncoding("shift_jis"));
            sw.Write(text);
            sw.Close();

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Set_No();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Shin = 0;                               //手順位置
            SShin = 0;                              //メイン配列書き込み位置
            Back = 0;                               //現在の戻り位置
            XBack = 0;                              //現在の位置の戻り数字
            t = 0;                                  //時間計算用
            LoopFlg = true;

            for(int i = 0; i < 10; i++)
            {
                NBack[i, 0] = 0;
                NBack[i, 1] = 0;
            }

            for (int i = 0; i < Con.CalcMax; i++) Undo[i] = 0;

            for (int i = 0; i <=9; i++)
            {
                for(int j = 0; j <= 9; j++)
                {
                    No[0, i, j] = 0; 
                }
            }

            label1.Text = "開始";
            label2.Text = "終了";
            Set_No();
            BGamen();

            button1.Enabled = true;

        }
    }

    static class Con
    {
        public const int CalcMax = 999990; // 配列上限
    }


}

ソース群

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

.NET Coreの画像処理ライブラリはどれが良い?

概要

  • 本記事はMicrosoft 開発者ブログの引用で、ConclusionをDeeplで和訳、整理したものになります。
  • 詳細はリンク先を参照ください。パフォーマンスや品質についても述べられています。
  • 2017年1月時点の情報なので、今は状況が変わっているかもしれません。

結論

.NET Core上での画像処理のためのライブラリは、さまざまな要件に対応できるように、今日では多くの選択肢がありますが、近い将来さらに多くの選択肢が出てくるでしょう。

  • パフォーマンスを優先するならば、CoreCompat.System.Drawingが良い
    • ただし、Windowsサーバーのシナリオでのロック問題がアプリケーションを停止させてしまわない場合に限る
  • SkiaSharpは、Linuxのセットアップ問題が解決されれば、品質を損なうことなくパフォーマンスを提供する素晴らしい選択肢となる
  • 品質を最優先に考え、Windowsのみで動作する場合、MagicScalerはパフォーマンスを犠牲にすることなく、素晴らしい選択肢となる
  • ファイルタイプのサポートを優先するのであれば、Magick.NETが良い
    • ただし、クロスプラットフォームのサポートはまだ不十分
  • 現時点で利用可能な唯一の純粋なマネージドコードライブラリであるImageSharp
    • その性能はMagick.NETに近い
    • ネイティブに依存せず、.NET Coreのどこでも動作することを保証している
    • このライブラリはまだアルファ版であり、特に将来のSpanとrefリターンの使用により、大幅なパフォーマンスの向上が見込まれる。

私見

.NET Coreはどのプラットフォームでも動作するという点が強みであると考えています。したがって、上記の記事を読む限りでは、ImageSharpが最も有力であるかなと思いました。
ただ、2年前の記事であるので、ちゃんと選定したい場合には各ライブラリの対応状況を確認したほうが良いと思われます。

.NET Coreの画像処理ライブラリに知見を持つ人がいらっしゃれば是非コメントをお願いします!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WPFアプリにおいてタイマ処理でUIを更新できない場合の対処法

はじめに

本記事は、開発で得た小さなTipsを備忘録として残すことを目的としています。

遭遇した問題

WPFアプリにおいてこちらのタイマクラスを使っている。タイマ時間経過時に実行されるハンドル処理内で、Dispathcerクラスを使ってUI更新をするとUIスレッドにアクセスできず、例外が出てしまう。

対処法

こちらのSystem.Windows.Threading.DispatcherTimerクラスを使えば、タイマ時間経過後の処理は必ずUIスレッドで実施されるため、Dispathcerクラスを使わずとも例外発生せずUI更新できる。
使い方はこちらの記事を参照のこと。

まとめ

遭遇した問題は自分のDispathcerクラスの使い方が不適切で発生している可能性もあるが、タイマ処理内でUI更新処理をすることが初めからわかっている場合は、System.Windows.Threading.DispatcherTimerクラスを使うのが良いと個人的に感じた。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

『眠気吹っ飛ばす作業用アプリ』【暖かい目で見てね】

なぜつくったの?

寝落ちでぴえんしそうになったから

4.gif

作ったもの

  • 常駐するWPFアプリケーション
    GitHub リリースページ
    Github初心者感すごいですが、気にしないでください

概要gif

3.gif

解決したい課題

寝落ちせずに作業がしたい

私の趣味は、『締め切りギリギリに徹夜で作業や課題をすること
この趣味は、寝落ちする可能性をぬぐい切れません。
そこで、寝落ちしないようなアプリケーションを作成した。

こうなってほしい

1.作業中に常駐する

2.マウスとキーボードの入力が一定時間止まる

3.設定したアラーム音を鳴らす

4.びっくりして起きる

問題点

気持ちよく寝ているところを起こされると不機嫌になってしまう

実装した処理(折り畳み:ソースコード)

入力が一定時間ないことを判別する
public static class User32Interop{
/// 最終操作からの経過時間
/// </summary> ミリ秒で表示される Ex. 1sec -> 1000, 5sec -> 5000
    public static TimeSpan GetLastInput(){
        var plii = new LASTINPUTINFO();
        plii.cbSize = (uint)Marshal.SizeOf(plii);
        if (GetLastInputInfo(ref plii))
            return TimeSpan.FromMilliseconds(Environment.TickCount - plii.dwTime);
        else
            throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
    }
    [DllImport("user32.dll", SetLastError = true)]
    static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
    struct LASTINPUTINFO{
        public uint cbSize;
        public uint dwTime;
    }
}


アラーム音を鳴らす
SoundFilePlay.cs
string SoundFilePath = SleepDown.Properties.Settings.Default.FilePath;
string FileExtension = System.IO.Path.GetExtension(SoundFilePath);
switch (FileExtension){
    case ".mp3"://This is fall through so it's not that i forget break;
    case ".wav":
    case ".flac":
        Microsoft.SmallBasic.Library.Sound.PlayAndWait(SoundFilePath);
        break;

    default:
        MessageBox.Show("音声ファイルは\n対応した拡張子を設定してください");
        break;
}


再生する音源をローカルファイルから選択可能にする
GetFilePath.cs
//設定に音源ファイルのパスを保存しているため
//パスを取得
var FileDialog = new Microsoft.Win32.OpenFileDialog();
FileDialog.Title = "開くファイルを選択してください";
FileDialog.Filter = "mp3ファイル|*.mp3|wavファイル|*.wav|flacファイル|*.flac";
if (FileDialog.ShowDialog() == true){
    SoundFilePath = FileDialog.FileName;
}

実装したい処理

  • 再生音源の音量調整
  • アラーム音を再生途中で入力があった場合の途中停止

最後に

もし読んでくれた人がいたならありがとうございます
深夜テンションでヒャッハー!して書いたのでわけわからないところはご愛嬌で頼んます。

ps.
初めて書いたのでC#もQiitaもぐちゃぐちゃです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む