###疑問
wpfについてなんですが、コントロールからイベントを作成するとmainwindow.xaml.csにイベントが追加されます。数多くのコントールがすべてここに追加されるとごちゃごちゃになりませんか?
###質問
例えば別のファイルを自分で作成して、そちらにコントロールを追加することはできるでしょうか?また一般的でしょうか。
想像ですが、イベントだけはmainwindow.xaml.csにすべて書いて、処理部分は別のファイルに書くという感じでしょうか?
こういった概念的なことは、なんと調べたらいいのかわかりません。
セオリーがあれば教えてください。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
ゴチャゴチャにならないよう、MVVM という手法を使うのが一般的です。
また、ファイルを分けたいだけなら、C# の partial キーワードを使うことができます。
投稿2019/05/18 01:16
総合スコア28660
0
ベストアンサー
どの程度の内容を難しいと感じるのか(何をやって何を難しいと思ったのか)、また、どのぐらいの知識を身につけたいを思っているのかわからないので何とも言えませんが…
それなりにまとまってそうなのはこんなサイトでしょうか。
https://www.tutorialspoint.com/mvvm/
ぱっと検索してみた感じだと、日本語のその手のサイトは情報が少なすぎたり、分散してたり、内容が古かったりするようなので、どうしても日本語で、という場合は本屋で書籍等を探してみてください。
投稿2019/05/19 16:28
総合スコア8949
0
WPFの場合、最も一般的なのはMVVMパターンによる実装ですが、WinForms等でもIDEからイベントハンドラを生成すると一つのファイルにまとめて作成されます。ファイルを分けようと何をしようと、イベントハンドラを使いたいのであれば、最低限どこかにその定義がないといけないので、一つのファイルに定義される方がむしろまとまってるとさえ言えます。
どの程度のレベルから「ごちゃごちゃする」と感じるかは個人差があると思いますが、イベントハンドラの中に「やりたいことを全て書く」という方法をとってしまうと、可読性が著しく落ちので良くない、というのは昔から言われています。
必要なのは「関心の分離」であり、MVVMはバインドという機構を使って、イベントへの紐づけの部分(XAML)と、その内部処理(ViewModel)で分ける方法です。
この場合、いわゆる「イベントハンドラ」のコードは原則不要になります。(その内容はViewModelに移動できるため)
WPFという前提ならこの方法で構いませんが、もっと一般化すればUI部品はデータの入力・出力のための最低限の処理だけを記述し、そのデータを加工するなどの処理は別のオブジェクトに任せる、という考え方が「セオリー」じゃないでしょうか。
他のコメントで仰っているregionを使うとIDEで折り畳むことはできますが、ファイル内の記述そのものは減ってないので、あまり意味はないと思います。(むしろ、それで「ごちゃごちゃしない」と思って多用されても困るので、お勧めしたくないぐらいです)
投稿2019/05/19 04:31
総合スコア8949
0
質問者さんが書かれている方法はWinForms等と同じイベントハンドラで処理する方法ですが、WPFではZushinさんが書かれているように、MVVMを使用することが多いです。
次のようにViewModelでCommandをプロパティとして公開し、View(XAML)側でCommandをバインドして呼び出します。
汎用的な処理であれば、BehaviorやTriggerActionを使うこともあります。
XAML
1<Window x:Class="WpfApp1.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 7 xmlns:ie="http://schemas.microsoft.com/expression/2010/interactions" 8 xmlns:local="clr-namespace:WpfApp1" 9 mc:Ignorable="d" 10 Title="MainWindow" Height="450" Width="800"> 11 12 <Window.DataContext> 13 <local:MainWindowViewModel /> 14 </Window.DataContext> 15 16 <StackPanel Orientation="Vertical"> 17 <!-- Commandに対応するイベント(Buttonの場合はClickイベント)を処理する場合 --> 18 <Button Content="{Binding Text}" Command="{Binding ClickCommand}" /> 19 20 <!-- Commandプロパティを持たないかCommandに対応しないイベントを処理する場合 --> 21 <Button Content="{Binding Text}"> 22 <i:Interaction.Triggers> 23 <i:EventTrigger EventName="Click"> 24 <i:InvokeCommandAction Command="{Binding ClickCommand}" /> 25 </i:EventTrigger> 26 </i:Interaction.Triggers> 27 </Button> 28 </StackPanel> 29</Window>
C#
1using System; 2using System.Collections.Generic; 3using System.ComponentModel; 4using System.Runtime.CompilerServices; 5using System.Windows.Input; 6 7namespace WpfApp1 { 8 9 class MainWindowViewModel: BindableBase { 10 11 public string Text { 12 get => this._text; 13 set => this.SetValue( ref this._text, value ); 14 } 15 private string _text = ""; 16 17 public ICommand ClickCommand { get; } 18 19 public MainWindowViewModel() { 20 this.Text = "None"; 21 this.ClickCommand = new SimpleCommand( () => this.Text += "Click!" ); 22 } 23 } 24 25 class BindableBase: INotifyPropertyChanged { 26 public event PropertyChangedEventHandler PropertyChanged; 27 28 protected bool SetValue<T>( ref T currentValue, T newValue, [CallerMemberName] string memberName = "" ) { 29 if( !EqualityComparer<T>.Default.Equals( currentValue, newValue ) ) { 30 currentValue = newValue; 31 this.PropertyChanged?.Invoke( this, new PropertyChangedEventArgs( memberName ) ); 32 return true; 33 } 34 return false; 35 } 36 } 37 38 class SimpleCommand: ICommand { 39 public event EventHandler CanExecuteChanged; 40 41 private Action Action { get; } 42 43 public SimpleCommand( Action action ) => this.Action = action; 44 45 public bool CanExecute( object parameter ) => true; 46 47 public void Execute( object parameter ) => this.Action?.Invoke(); 48 49 } 50} 51
投稿2019/05/18 16:29
総合スコア2573
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/05/18 21:04
2019/05/19 04:44