質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

MVVM

MVVM(Model View ViewModel)は構築上のデザインパターンで、表現ロジック(ViewModel)によってデータ(Model)からページ(View)を分離させます。

Q&A

解決済

2回答

2649閲覧

MVVMの考え方/特異な項目の追加

cisdur

総合スコア46

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

MVVM

MVVM(Model View ViewModel)は構築上のデザインパターンで、表現ロジック(ViewModel)によってデータ(Model)からページ(View)を分離させます。

0グッド

1クリップ

投稿2016/06/26 00:46

編集2016/06/26 00:54

###概要
現在、C#でWPFアプリケーションを作成しています。一種のメモ帳なのですが、Evernoteのように、タグ管理ができるようにしたいと考えております。手始めに、「データベースから取得したタグ一覧をリストボックスに表示する」ようにしているのですが、MVVMの考え方が身についておらず、四苦八苦しています(むしろ、オブジェクト指向の理解が足りない可能性も)。
また、表示項目に「タグを指定しない」という選択肢をどう追加するかにも悩んでいます。
###質問①
以下のコード、TagListVMクラスが無駄に見えます。startupでTagListVMのコンストラクターを呼び出し、さらにその中でTagListのコンストラクターを呼ぶという構成も変です。また、変数名なども全体的に極めて分かりにくいです(tagListって何回出てくるねん!)。あと、publicだらけです。改善の指針を提示してくださるとありがたいです。
###質問②
以下のコードに、「タグを指定しない」選択肢を加えるには、どのようにするのがよいでしょうか。「Tagクラスにコンストラクターを追加→Tag notSpecify = new Tag(...)などとして生成→tagListにadd」という方法は考えましたが、「タグを指定しない」というのはタグではないので、ふさわしくないですよね。TagListをTagCommandListのようにして……というのも考えたのですが、無駄に複雑化する気がします。
###コード

xml

1<ListBox ItemsSource="{Binding tagList}" DisplayMemberPath="name" />

C#

1 public partial class App : Application 2 { 3 public void startup(object sender, StartupEventArgs e) 4 { 5 TagListVM tagListVM = new TagListVM(); 6 } 7 } 8 9 public class TagList 10 { 11 public List<Tag> tagList { get; private set; } 12 13 public TagList() 14 { 15 tagList = new List<Tag>(); 16 17 using (SQLiteConnection connection = new SQLiteConnection("DataSource = xxxx.db")) 18 { 19 connection.Open(); 20 using (DataContext context = new DataContext(connection)) 21 { 22 Table<Tag> tagTable = context.GetTable<Tag>(); 23 IQueryable<Tag> queryResult = 24 from t in tagTable 25 select t; 26 foreach (Tag t in queryResult) 27 { 28 tagList.Add(t); 29 } 30 } 31 } 32 } 33 } 34 35 [Table(Name = "tag")] 36 public class Tag 37 { 38 [Column(Name = "tagID", DbType = "INT")] 39 public int id { get; private set; } 40 41 [Column(Name = "name", DbType = "TEXT")] 42 public string name { get; private set; } 43 } 44 45 public class TagListVM 46 { 47 public List<Tag> tagList { get; private set; } 48 49 public TagListVM() 50 { 51 tagList = new TagList().tagList; 52 } 53 } 54

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

まず気になったのが、
class TagListVMのメンバのpublic List<Tag> tagList
これ、どうしてclass TagListのインスタンスはコンストラクタ内で変数に格納せずにプロパティのList<Tag> tagList だけをclass TagListVMに残そうとしたのか
自分ならclass TagListVMのprivateでclass TagListのインスタンスを格納して、public List<Tag> tagListプロパティはTagList.tagListを返す形にしてgetのみ

同様に、class TagListのpublic List<Tag> tagListもprivateで実体を持っておいてpublicにはgetのみでprivateのインスタンスを上げる形で
setまでpublicにすると、外から勝手に置き換えられてしまうので
class TagListVMに至ってはclass TagListをnewした後受けずに放置しているので、外部から差し替えられたらコンストラクタで作る意味が完全になくなってしまうしクラスのメンバが中身を把握できなく外部から好き勝手いじられるようになってしまうと、そのうち自分一人で作っていてもすっかり忘れて変なミスを引き起こすと思う

あと、List<Tag> tagList自身は他のwindowでも使いまわすのならいいけど、使いまわさないのであるなら、App.startupでTagListVM tagListVM = new TagListVM();せずに使用するwindowのcontextへnewしてぶち込むかなぁ
いまいちどう使うのかもよくわからないので曖昧なことしか書けないけど、見えてる内容だけだととりあえずはそんな感じに変更するかな

WPFって書いてあるのでTagListVMは他にもバインドする項目があるのならそれの詰め合わせにする感じの使い方だからこれ一つしかない現状だと無駄に見えるのは仕方がない

投稿2016/06/28 04:19

len_souko

総合スコア1348

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

なんだか自分が20年前に書いたプログラムを見ているようです。
所感ですが、MVVM以前にClass設計について復習するのが良いかと思いますが、回答してみます。

質問1

ご自分でお気づきのようですが、思っていることは正しいです。
まず適切な変数名を付けること、それから変数のスコープをきちんとつけること(publicばっかりやめる)
そうすると、だいぶ読みやすくなるかと思います。
現状、行数の割にはめちゃくちゃ読みにくいコードなので、まずもう少し読み易くして欲しいです。

質問2

今のソースで自分ならTagListのコンストラクタでやるか、中身追加した後の最後に追加するとかですかね。

投稿2016/06/26 02:18

azurite2016

総合スコア69

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cisdur

2016/06/26 22:06

ご回答ありがとうございます。 なるほど、やっぱり読みにくいですよね。 TagListVM(VMはViewModelの略です)さえ外せば、そこそこ見られるコードだとは思ったのですが……。 最初はTagListVMなんてクラスはなかったのですが、TagListとTagはModelに属するクラスですので、ViewにTagListの内容を反映させるためには、間をつなぐViewModelに属するクラスが必要かと思って追加しました。 これをどうするかが一番の悩みです。 publicの件については、どれをprivateにしても動かなくなってしまうのですが、どうするのが適切でしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問