編集:正しい軌道に乗ったので、答えをマークしました。残っている唯一の問題は設計上の問題のようであり、ボードルールによれば、別の質問として尋ねるべきです。ここで私のフォローアップの質問を参照してください: https://stackoverflow.com/questions/19744475/design-issue-how-to-approach-this-specific-task
カスタム オブジェクトのリストを DataGrid にバインドしようとしています。ストレート バインドは簡単に思えますが、クラスに直接表示されない追加のフィールドに複雑な数式を指定する必要があります。また、グリッド内のデータを編集して、関連するフィールドの更新を取得できるようにしたいと考えています。説明するのが本当に難しいので、例を示しましょう。アイテムのある部屋に単純化します。各アイテムは赤と青にすることができます。
私のクラスは次のようになります。
public class room
{
public string strRoomName { set; get; }
public string strItemname { set; get; }
public int intRedItem { set; get; }
public int intBlueItem { set; get; }
}
今、dataTable.ItemSource = myList; を使用すると、私はこのようなものを得る:
nr. | room | name | red | blue
1. living room, ball, 2, 1
2. sleeping room, bunny, 4, 1
3. living room, chair, 3, 2
4. kitchen, ball, 4, 7
5. garage, chair, 1, 4
複雑な部分については、助けが必要です。すべてのアイテムを赤と青の同じ数字にしたい。そして、これは当てはまらないため、部屋ごとの「不均衡」と、次のようにグローバルに見たいと思います。
nr. | room | name | red | blue | missing | global red | global blue | global missing
1. living room, ball, 2, 1, 1 blue, 6, 7, 1 red
2. sleeping room, bunny, 4, 1, 3 blue, 4, 1, 3 blue
3. living room, chair, 3, 2, 1 blue, 4, 6, 2 red
4. kitchen, ball, 4, 7, 3 red, 6, 7, 1 red
5. garage, chair, 1, 4, 3 red, 4, 6, 2 red
ご覧のとおり、これは Excel の数式のように見えますが、C# コードでこれを処理する方法がわかりません。また、同じ行のデータを使用する必要があることもわかりますが、1 つのプロパティ (アイテム名) に一致する他の行からデータを取得することもできます。
また、1行目の青い値= 1を値= 2に変更すると、1行目が次のようになります。
1. living room, ball, 2, 2, even, 6, 8, 2 red
および大まかな行 4 を次のように変更する必要があります。
4. kitchen, ball, 4, 7, 3 red, 6, 8, 2 red
編集:あなたの答えを読み、ヒントを実装するスキルをテストした後、クラスとして次のコードを作成しました:
public class RoomList : ObservableCollection<room>
{
public RoomList() : base()
{
Add(new room() { strRoomName = "living room", strItemname = "ball", intRedItem = 2, intBlueItem = 1 });
Add(new room() { strRoomName = "sleeping room", strItemname = "bunny", intRedItem = 4, intBlueItem = 1 });
Add(new room() { strRoomName = "living room", strItemname = "chair", intRedItem = 3, intBlueItem = 2 });
Add(new room() { strRoomName = "kitchen", strItemname = "ball", intRedItem = 4, intBlueItem = 7 });
Add(new room() { strRoomName = "garage", strItemname = "chair", intRedItem = 1, intBlueItem = 4 });
}
}
//rooms
public class room : INotifyPropertyChanged
{
public string strRoomName { set; get; }
public string strItemname { set; get; }
private int _intRed = 0;
private int _intBlue = 0;
public int intRedItem
{
get { return _intRed; }
set
{
_intRed = value;
NotifyPropertyChanged("intRedItem", "strMissing");
}
}
public int intBlueItem
{
get { return _intBlue; }
set
{
_intBlue = value;
NotifyPropertyChanged("intBlueItem", "strMissing");
}
}
public string strMissing
{
get
{
int missingCount = intRedItem - intBlueItem;
return missingCount == 0 ? "Even" : missingCount.ToString();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(params string[] propertyNames)
{
if (PropertyChanged != null)
{
foreach (string propertyName in propertyNames)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
編集 1:「不足している」フィールドがすぐに機能するようになりました。そのヒントに感謝します。想像していたほど簡単で、将来のプロジェクトに大いに役立ちます。
Edit2: クラスにプライベート ダミー変数を追加して StackOverflow-Error を修正しました。上記のコードを参照してください。
Edit3:リソースも修正しました。昨日まったく同じコードを使用したことを誓っていますが、現在は機能しています。しかたがない。
唯一の本当の問題が残っています:
他のオブジェクトのプロパティに基づいてプロパティを設定するにはどうすればよいですか? 「globalRed」プロパティは、リストまたはコレクションをループする必要がありますが、どちらもオプションではないようです。少なくとも、私は通常これをコードで行うようではありません。「listRooms」はプロパティ ゲッターに表示されません。また、新しいオブジェクトが追加された後、これを再度ループする必要があります。otify メソッドもこれを処理すると思いますが、そもそもループするにはどうすればよいですか?
そして、理解を深めるためにもう 1 つ質問します。
上記のコレクションがリストアプローチよりも好ましい理由を簡単に説明できる人はいますか? 私がテストできた限り、それらは同じように動作します。
//the list-Way
datagridRooms.ItemsSource = listRooms.Where(x=>x.strRoomName == "living room");
//indentical with the collection-way...
datagridRooms.ItemsSource = new RoomList().Where(x=>x.strRoomName== "living room");