WPF アプリケーションの 多言語切替

Similar documents
WPF アプリケーションの 多言語切替

WPF アプリケーションの 多言語切替


DEMO1 まずはやってみよう アクティビティをダブルクリック 作成 - プロジェクト C# => Workflow CodeActivity をぽとぺ シーケンシャルと ステートマシン それぞれのコ ンソールアプリ あとライブラリがある びっくりマークは足りていないあかし プロパティをみると判別で

YKToolkit.Controls 取扱説明書 Ver YKSoftware

Prog2_12th

XAML Do-It-Yourself 第 3 回ベントとトリガー XML Do-It-Yourself 第 3 回目は ベント処理とトリガーについて学習します Windows フォームゕプリケーションでは たとえば ボタンが押された というベントに対応する処理 ( ベントハンドラー ) を記述する

WPF Bindingの威力

Microsoft PowerPoint ppt

Windows Presentation Foundation

基礎計算機演習 実習課題No6

Java 基礎問題ドリル ~ メソッドを理解する ~ 次のプログラムコードに 各設問の条件にあうメソッドを追加しなさい その後 そのメソッドが正しく動作することを検証するためのプログラムコードを main メソッドの中に追加しなさい public class Practice { // ここに各設問

Visual Studio Do-It-Yourself 第 9 回ユーザーコントロール 第 6 回のリソースから第 8 回のテンプレートで さまざまな方法でコントロールをカスタマズできるこ とを学びました 今回のテーマであるユーザーコントロールは 既存の一つのコントロールをカスタマ ズするのではな

Abstract Kinect for Windows RGB Kinect for Windows v Kinect for Windows v2

VB.NETコーディング標準

JavaプログラミングⅠ

intra-mart Accel Platform — IM-Repository拡張プログラミングガイド   初版  

TestDesign for Web

SharpShooter Reports.WPF 基本的な使い方 Last modified on: November 15, 2012 本ドキュメント内のスクリーンショットは英語表記ですが SharpShooter Reports JP( 日本語版 ) では日本語で表示されます

intra-mart Accel Platform — イベントナビゲータ 開発ガイド   初版  

1_cover

スライド 1

.NETプログラマー早期育成ドリル ~VB編 付録 文法早見表~

C#の基本

グラフの探索 JAVA での実装

XAML Do-It-Yourself シリーズ 第 7 回テンプレート -1-

文字列操作と正規表現

Microsoft PowerPoint - Windows Presentation Foundation (WPF) 3.5 の新機能

目的 泡立ち法を例に Comparableインターフェイスの実装 抽象クラスの利用 型パラメタの利用 比較 入替 の回数を計測

TOEIC

intra-mart Accel Platform — イベントナビゲータ 開発ガイド   初版   None

Visual Studio2008 C# で JAN13 バーコードイメージを作成 xbase 言語をご利用の現場でバーコードの出力が必要なことが多々あります xbase 言語製品によっては 標準でバーコード描画機能が付加されているものもあるようで す C# では バーコードフォントを利用したりバー

Microsoft認定資格問題集DEMO(70-513)

PowerPoint プレゼンテーション

平成 29 年度卒業研究 初心者のためのゲームプログラミング用 教材の開発 函館工業高等専門学校生産システム工学科情報コース 5 年 25 番細見政央指導教員東海林智也

とても使いやすい Boost の serialization

Sparkline for WPF

基本情報STEP UP演習Java対策

ファイルを直接編集する画面を切り替えることができる. 図 3 標準のレイアウトを削除する (2) グラフィカル レイアウト画面で LinearLayout(Vertical) を追加するパレットウィンドウの レイアウト の中にある LinearLayout(Vertical) をドラッグして, 編集

問 次の Fortran プログラムの説明及びプログラムを読んで、設問に答えよ。

Prog2_15th

Chart3D for WPF/Silverlight

プログラミング基礎I(再)

Javaセキュアコーディングセミナー2013東京第1回 演習の解説

1.SqlCtl クラスリファレンス SqlCtl クラスのリファレンスを以下に示します メソッドの実行中にエラーが発生した場合は標準エラー出力にメッセージを出力します (1)Connect() メソッド データベースへ connect 要求を行います boolean Connect(String

PowerPoint Presentation

解答上の注意 1 解答は 解答 紙の問題番号に対応した解答欄にマークしなさい 2 選択肢は 問ごとに 意されています 問 1の選択肢は 問 2で使 しません 3 選択肢は量が多いため 探しやすさの観点よりグループ分けされています グループ分けに合わせて解答欄が区切られていますが 横 1 列で問題 1

VB 資料 電脳梁山泊烏賊塾 音声認識 System.Speech の利用 System.Speech に依るディクテーション ( 音声を文字列化 ).NetFramework3.0 以上 (Visual Studio 2010 以降 ) では 標準で System.Speech が用意されて居るの

Microsoft PowerPoint Java基本技術PrintOut.ppt [互換モード]

JavaプログラミングⅠ

JAVA とテンプレート

グラフィックス 目次

Microsoft PowerPoint - chap10_OOP.ppt

プロセス間通信

Microsoft PowerPoint - ●SWIM_ _INET掲載用.pptx

第1章 ビジュアルプログラミング入門

H:\Projects2013\MatrixLibrary\MatrixLibrary\MatrixLibrary.cs /* ************************ * * * 行列関係のライブラリ * * * ************************ * * 行列の要素 A.V

プログラミング入門1

Javaの作成の前に

LogisticaTRUCKServer-Ⅱ距離計算サーバ/Active-Xコントロール/クライアント 概略   

A, K, Q, J, 10, 9, 8, 7, 6, 5, 4, 3,

Exam : 1z1-809-JPN Title : Java SE 8 Programmer II Vendor : Oracle Version : DEMO Get Latest & Valid 1z1-809-JPN Exam's Question and Answers 1 from Ac

Microsoft認定資格問題集(70-483_demo)

第 3 回 Java 講座 今回の内容 今週の Java 講座はコレクション 拡張 for 文, ガベージコレクションについて扱う. 今週の Java 講座は一番内容が薄いも のになるだろう. コレクション コレクションとは大きさが決まっていない配列だと考えればよい. コレクションには List 先

mazec テクニカルガイド第5版(Android版)

PowerPoint プレゼンテーション

C#の基本2 ~プログラムの制御構造~

Brekeke PBX - Version 2.1 ARSプラグイン開発ガイド

スライド 1

JAVA入門

新・明解Java入門

Prog2_6th

WPFの初歩の初歩

メディプロ1 Javaプログラミング補足資料.ppt

Java言語 第1回

Microsoft Word _VBAProg1.docx

Microsoft Word - VB.doc

デジタル表現論・第4回

WebOTXマニュアル

HCI プログラミング 8 回目ボタン チェックボックス ラジオボタン 今日の講義で学ぶ内容 ボタンとアクションイベント ボタンのカスタマイズ チェックボックスとラジオボタン ボタンとアクションイベント 1 ボタンを配置してみましょう ボタンは ラベルと同じようにフォントやその色 画像の貼り付けなど

Javaプログラムの実行手順

Android Layout SDK プログラミング マニュアル

目次 1 はじめに WPF とは データバインディング バインディングモード コンバータ コマンド コレクションのデータバインディング 依存関係プロパティ...

ALG ppt

Prog2_10th

intra-mart Accel Platform

.NET Framework 4.0 世代の Expression Trees

PowerPoint Presentation

untitled

Microsoft PowerPoint - prog12.ppt

Web フォームアプリケーション開発基礎

GUIプログラムⅣ

Seasar.NET入門

Prog2_6th

XAML Do-It-Yourself シリーズ 第 8 回ゕニメーション -1-

ウィンドウ操作 応用

テキストファイルの入出力1

28th Embarcadero Developer Camp

Document Library for UWP

プラグイン

Transcription:

元に戻す操作の実装 YK S o f t w a r e 2015 年 8 月 7 日 @twyujiro15

プロフィール 加藤裕次郎 本職は製造業の開発業務 - 2009 年 4 月に入社 1982.03.03 生まれ ( うお座 ) 左利き ( お箸は右 ) twitter : @twyujiro15 プログラミング経験 Excel VBA MATLAB MATX C VC++ (Windows SDK) VC++ (MFC) WPF + C# 組み込みソフトウェア開発で初めてまともに C 言語 デバッグソフトで Visual C++(MFC Windows SDK) Excel 大好きマンだったので VBA も使用 - 2013 年 10 月 あるサンプルが "WPF" なるものでできていることを知る - 2015 年 8 月 これまでに 1 個のライブラリと 20 個以上のソフトを作成 1 / 30

今回のゴール 元に戻す / やり直し機能を実装する やり直し やり直し 元に戻す 元に戻す プロパティの変更を元に戻す / やり直す 2 / 30

せっかくなので基本から順に説明します MVVM パターン View (XAML) UI 要素の構成 EventHandler 表示の更新 PropertyChanged (INotifyPropertyChanged) Command Execute (ICommand) EventHandler 状態の更新 ViewModel (C#) 表示する情報の保持 Model の操作 Model (C#) アプリケーションの根本 3 / 30

ICommand の実装 (1/2) using System.Windows.Input; public class DelegateCommand : ICommand /// 新しいインスタンスを生成します /// <param name="execute"> コマンドの処理内容を指定します </param> public DelegateCommand(Action<object> execute) : this(execute, null) /// 新しいインスタンスを生成します /// <param name="execute"> コマンドの処理内容を指定します </param> /// <param name="canexecute"> コマンド実行可能判別の処理内容を指定します </param> public DelegateCommand(Action<object> execute, Func<object, bool> canexecute) this._execute = execute; this._canexecute = canexecute; /// コマンドの処理内容を保持します private Action<object> _execute; /// コマンド実行可能判別の処理内容を保持します private Func<object, bool> _canexecute; 4 / 30

ICommand の実装 (2/2) #region ICommand のメンバ /// コマンド実行可能判別をおこないます /// <param name="parameter"> コマンドパラメータを指定します </param> /// <returns> コマンドが実行可能な場合に true を返します </returns> public bool CanExecute(object parameter) return this._canexecute!= null? this._canexecute(parameter) : true; /// コマンド実行可能判別に変更があった場合に発生します public event System.EventHandler CanExecuteChanged add CommandManager.RequerySuggested += value; remove CommandManager.RequerySuggested -= value; /// コマンドを実行します /// <param name="parameter"> コマンドパラメータを指定します </param> public void Execute(object parameter) if (this._execute!= null) this._execute(parameter); #endregion ICommand のメンバ 5 / 30

IPropertyChanged の実装 (1/2) using System.ComponentModel; using System.Runtime.CompilerServices; /// <c>system.componentmodel.inotifypropertychanged</c> インターフェースを実装した抽象クラスです public abstract class NotificationObject : INotifyPropertyChanged #region INotifyPropertyChanged のメンバ /// プロパティ値に変更があった場合に発生します public event PropertyChangedEventHandler PropertyChanged; #endregion INotifyPropertyChanged のメンバ /// プロパティ値変更通知イベントを発行します /// <param name="propertyname"> プロパティ名を指定します </param> protected virtual void RaisePropertyChanged([CallerMemberName]string propertyname = null) var h = this.propertychanged; if (h!= null) h(this, new PropertyChangedEventArgs(propertyName)); 6 / 30

IPropertyChanged の実装 (2/2) /// プロパティ値変更のためのヘルパです /// <typeparam name="t"> プロパティの型 </typeparam> /// <param name="target"> プロパティの実体を指定します </param> /// <param name="value"> 変更後の値を指定します </param> /// <param name="propertyname"> プロパティ名を指定します </param> /// <returns> プロパティ値に変更があった場合に true を返します </returns> protected virtual bool SetProperty<T>(ref T target, T value, [CallerMemberName]string propertyname = null) if (!object.equals(target, value)) System.Diagnostics.Debug.WriteLine(value.ToString() + " に変更されました "); target = value; RaisePropertyChanged(propertyName); return true; 変更があると出力ウィンドウに表示される return false; 7 / 30

とりあえず基本を実装しました MVVM パターン View (XAML) UI 要素の構成 EventHandler 表示の更新 PropertyChanged (INotifyPropertyChanged) Command Execute (ICommand) EventHandler 状態の更新 ViewModel (C#) 表示する情報の保持 Model の操作 Model (C#) アプリケーションの根本 8 / 30

こんなモデルを用意して Model (C#) using System.Collections.Generic; /// 人物データリストを表します public class People : List<Person> /// 人物データを表します public class Person /// 新しいインスタンスを生成します /// <param name="name"> 名前を指定します </param> /// <param name="age"> 年齢を指定します </param> public Person(string name, int age) this.name = name; this.age = age; /// 名前を取得または設定します public string Name get; set; /// 年齢を取得または設定します public int Age get; set; /// 人物データを文字列として表現します /// <returns> 文字列を返します </returns> public override string ToString() return string.format("0 (1 才 )", this.name, this.age); 9 / 30

表示する情報を決める (1/2) ViewModel (C#) using UndoRedoApp.Models; /// MainView に対する ViewModel クラスです public class MainViewModel : NotificationObject /// 新しいインスタンスを生成します public MainViewModel() this._people = new People() new Person(" ゆうじろ 1", 11), new Person(" ゆうじろ 2", 12), new Person(" ゆうじろ 3", 13), new Person(" ゆうじろ 4", 14), new Person(" ゆうじろ 5", 15), ; this._selectedperson = People[0]; private People _people; /// 人物データリストを取得します public People People get return _people; private Person _selectedperson; /// 選択された人物データを取得または設定します public Person SelectedPerson get return _selectedperson; set SetProperty(ref _selectedperson, value); 10 / 30

表示する情報を決める (2/2) ViewModel (C#) private string _text = " サンプルテキスト "; /// string 型の値を取得または設定します public string Text get return _text; set SetProperty(ref _text, value); private int _value; /// int 型の値を取得または設定します public int Value get return _value; set SetProperty(ref _value, value); 公開プロパティは Text プロパティ Value プロパティ People プロパティ SelectedPerson プロパティ 11 / 30

公開された情報を表示する View (XAML) <Window x:class="undoredoapp.views.mainview" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainView" Height="300" Width="300"> <StackPanel> <TextBox Text="Binding Text" /> <TextBox Text="Binding Value" /> <ComboBox ItemsSource="Binding People" SelectedItem="Binding SelectedPerson"> <ComboBox.ItemTemplate> <DataTemplate> <StackPanel> <TextBlock Text="Binding Name" /> <TextBlock Text="Binding Age, StringFormat=' 年齢 : 0'" Margin="20,0,0,0" /> </StackPanel> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox> </StackPanel> </Window> 12 / 30

ちょっと動かしてみましょう 出力ウィンドウにも表示されている 13 / 30

前置きが長くなりましたが 今回のゴール やり直し やり直し 元に戻す 元に戻す プロパティの変更を元に戻す / やり直す 14 / 30

まずはプロパティ変更操作履歴用クラス (1/2) using System; /// 特定のアクションを保持し 任意のタイミングで実行するためのクラスです internal class SetPropertyHistory /// アンドゥアクションを保持します private Action _undoaction; /// リドゥアクションを保持します private Action _redoaction; /// 保持しているアンドゥアクションを実行します public void UnDo() this._undoaction(); /// 保持しているリドゥアクションを実行します public void ReDo() this._redoaction(); 15 / 30

まずはプロパティ変更操作履歴用クラス (2/2) /// 新しいインスタンスを生成します /// <param name="undoaction"> アンドゥアクションを指定します </param> /// <param name="undoaction"> リドゥアクションを指定します </param> public SetPropertyHistory(Action undoaction, Action redoaction) if (undoaction == null) throw new ArgumentNullException(" 必ずアンドゥアクションを指定してください "); if (redoaction == null) throw new ArgumentNullException(" 必ずリドゥアクションを指定してください "); this._undoaction = undoaction; this._redoaction = redoaction; 16 / 30

NotificationObject 派生クラス (1/3) using System; using System.Collections.Generic; using System.Runtime.CompilerServices; /// アンドゥ機能を備えた <c>notificationobject</c> クラス派生のクラスです public abstract class UndoRedoNotificationObject : NotificationObject private Stack<SetPropertyHistory> _undostack; /// アンドゥする操作を溜めておくスタックを取得します private Stack<SetPropertyHistory> UndoStack get return _undostack?? (_undostack = new Stack<SetPropertyHistory>()); private Stack<SetPropertyHistory> _redostack; /// リドゥする操作を溜めておくスタックを取得します private Stack<SetPropertyHistory> RedoStack get return _redostack?? (_redostack = new Stack<SetPropertyHistory>()); 17 / 30

NotificationObject 派生クラス (2/3) private DelegateCommand _undocommand; /// 元に戻すコマンドを取得します public DelegateCommand UndoCommand get return _undocommand?? (_undocommand = new DelegateCommand( _ => var action = this.undostack.pop(); action.undo(); this.redostack.push(action);, _ => this.undostack.count > 0)); private DelegateCommand _redocommand; /// やり直しコマンドを取得します public DelegateCommand RedoCommand get return _redocommand?? (_redocommand = new DelegateCommand( _ => var action = this.redostack.pop(); action.redo(); this.undostack.push(action);, _ => this.redostack.count > 0)); 18 / 30

NotificationObject 派生クラス (3/3) /// プロパティ値変更のためのヘルパです /// <typeparam name="t"> プロパティの型 </typeparam> /// <param name="target"> プロパティの実体を指定します </param> /// <param name="value"> 変更後の値を指定します </param> /// <param name="action"> 変更前の値を引数として 変更を元に戻すためのアクションを指定します </param> /// <param name="propertyname"> プロパティ名を指定します </param> /// <returns> プロパティ値に変更があった場合に true を返します </returns> protected virtual bool SetProperty<T>(ref T target, T value, Action<T> action, [CallerMemberName]string propertyname = null) T oldvalue = target; bool ret = SetProperty(ref target, value, propertyname); if (ret) this.undostack.push(new SetPropertyHistory( () => // 元に戻す操作 action(oldvalue); RaisePropertyChanged(propertyName);, () => // やり直す操作 action(value); RaisePropertyChanged(propertyName); )); this.redostack.clear(); return ret; 19 / 30

操作履歴のスタックのイメージ (1/8) 例えばこんな操作をしたら 1. null から "1" に変更 現在の値 null 1 今回の操作を保持 UnDo(null) ReDo(1) UndoStack RedoStack 20 / 30

操作履歴のスタックのイメージ (2/8) 例えばこんな操作をしたら 1. null から "1" に変更 2. "1" から "2" に変更 現在の値 1 2 今回の操作を保持 UnDo(1) UnDo(null) ReDo(2) ReDo(1) UndoStack RedoStack 21 / 30

操作履歴のスタックのイメージ (3/8) 例えばこんな操作をしたら 1. null から "1" に変更 2. "1" から "2" に変更 3. 元に戻す ("2" から "1" に戻る ) 元に戻す操作を実行する スタックから取り出す 現在の値 2 1 UnDo(1) ReDo(2) スタックを移動する UnDo(1) ReDo(2) UnDo(null) ReDo(1) UnDo(1) ReDo(2) UndoStack RedoStack 22 / 30

操作履歴のスタックのイメージ (4/8) 例えばこんな操作をしたら 1. null から "1" に変更 2. "1" から "2" に変更 3. 元に戻す ("2" から "1" に戻る ) 4. "1" から "4" に変更 現在の値 1 4 今回の操作を保持 UnDo(1) UnDo(null) ReDo(4) ReDo(1) やり直し操作をクリア UndoStack RedoStack 23 / 30

操作履歴のスタックのイメージ (5/8) 例えばこんな操作をしたら 1. null から "1" に変更 2. "1" から "2" に変更 3. 元に戻す ("2" から "1" に戻る ) 4. "1" から "4" に変更 5. 元に戻す ("4" から "1" に戻る ) 元に戻す操作を実行する スタックから取り出す 現在の値 4 1 UnDo(1) ReDo(4) スタックを移動する UnDo(1) ReDo(4) UnDo(null) ReDo(1) UnDo(1) ReDo(4) UndoStack RedoStack 24 / 30

操作履歴のスタックのイメージ (6/8) 例えばこんな操作をしたら 1. null から "1" に変更 2. "1" から "2" に変更 3. 元に戻す ("2" から "1" に戻る ) 4. "1" から "4" に変更 5. 元に戻す ("4" から "1" に戻る ) 6. 元に戻す ("1" から null に戻る ) 元に戻す操作を実行する スタックから取り出す 現在の値 1 null UnDo(null) ReDo(1) スタックを移動する UnDo(null) ReDo(1) UnDo(null) ReDo(1) UnDo(1) ReDo(4) UndoStack RedoStack 25 / 30

操作履歴のスタックのイメージ (7/8) 例えばこんな操作をしたら 1. null から "1" に変更 2. "1" から "2" に変更 3. 元に戻す ("2" から "1" に戻る ) 4. "1" から "4" に変更 5. 元に戻す ("4" から "1" に戻る ) 6. 元に戻す ("1" から null に戻る ) 7. やり直す (null から "1" に変更 ) 現在の値 null 1 やり直し操作を実行する スタックを移動する UnDo(null) ReDo(1) スタックから取り出す UnDo(null) ReDo(1) UnDo(null) ReDo(1) UnDo(1) ReDo(4) UndoStack RedoStack 26 / 30

操作履歴のスタックのイメージ (8/8) 例えばこんな操作をしたら 1. null から "1" に変更 2. "1" から "2" に変更 3. 元に戻す ("2" から "1" に戻る ) 4. "1" から "4" に変更 5. 元に戻す ("4" から "1" に戻る ) 6. 元に戻す ("1" から null に戻る ) 7. やり直す (null から "1" に変更 ) 8. やり直す ("1" から "4" に変更 ) 現在の値 1 4 やり直し操作を実行する スタックを移動する UnDo(1) ReDo(4) スタックから取り出す UnDo(1) ReDo(4) UnDo(null) ReDo(1) UnDo(1) ReDo(4) UndoStack RedoStack 27 / 30

元に戻す / やり直しボタンを追加する View (XAML) <Window x:class="undoredoapp.views.mainview" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainView" Height="300" Width="300"> <StackPanel> <TextBox Text="Binding Text" /> <TextBox Text="Binding Value" /> <ComboBox ItemsSource="Binding People" SelectedItem="Binding SelectedPerson"> <ComboBox.ItemTemplate> <DataTemplate> <StackPanel> <TextBlock Text="Binding Name" /> <TextBlock Text="Binding Age, StringFormat=' 年齢 : 0'" Margin="20,0,0,0" /> </StackPanel> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox> <Button Content=" 元に戻す " Command="Binding UndoCommand" Margin="0,20,0,0" /> <Button Content=" やり直し " Command="Binding RedoCommand" /> </StackPanel> </Window> 28 / 30

実際に操作してみよう 元に戻す / やり直し機能が実現できましたか? やり直し やり直し 元に戻す 元に戻す 29 / 30

気になること プロパティ変更にしか対応していない - コレクションの要素変更を考慮する必要あり イベントハンドラの登録/ 解除に対応していない - Person クラスにイベントがあって MainViewModel が購読していたら - リストから消去したけど裏でイベントを拾ってしまうこともあり得る 30 / 30

ご清聴ありがとうございました S o f t w a r e