2012-02-01 4 views
0

に1つの辞書から要素を移動する私はいくつかのペア

Dictionary<DateTime, ObservableCollection<Car>> 

と辞書を持っていると私はCarの製造年を変えていて、KeyDateTimeが)私は移動する必要が年であるため、このCarからKeyValuePairまでは年末年始はKeyValuePairです。

ので、たとえば、私は2組持っていた:

1.1.1997 {Car1,Car2} 
1.1.1998 {Car3} 

をして

Car2.Production = Convert.ToDateTime("1.1.1998"); 

で私はそれを達成するための最も簡単な方法は何ですか

1.1.1997 {Car1} 
1.1.1998 {Car3,Car2} 

を持っている必要がありますか?

+2

これを行うには簡単な方法はありませんか。あなたは、あなたの 'Dictionary'の' Key'として、生産年の 'DateTime'を使って考え直すことができます。これがデータベースなら、あなたはかなり厄介な機能的依存関係を導入したでしょう。 – Yuck

+0

コード臭があることを知っていますが、これをリファクタリングする時間はあまりありません。私はそのコードで作業する必要があります。 – user278618

+0

'Production'値を変更するために個々の' Car'を引き出しているコード領域の 'Dictionary >'にアクセスできますか? – Yuck

答えて

2

代わりにこのデータにグループ化されたビューを使用するように思われるかもしれませんが、ここに述べたように質問に対処するコードソリューションがあります。複数のプロパティに対してこれを行う予定がある場合は、CarをDependencyObjectから継承させるか、それぞれに対してイベントを作成する代わりにINotifyPropertyChangedから実装することをお勧めします。

// The car class itself 
public class Car 
{ 
    // This event is raised when the production property changes 
    public event EventHandler<PropertyValueChange<DateTime>> ProductionChanged; 
    DateTime _production; // private data 
    public DateTime Production 
    { 
     get { return _production; } 
     set 
     { 
      if (value == _production) return; // don't raise the event if it didn't change 
      var eventArgs = new PropertyValueChange<DateTime>(_production, value); 
      _production = value; 
      // If anyone is "listening," raise the event 
      if (ProductionChanged != null) 
       ProductionChanged(this, eventArgs); 
     } 
    } 
} 
// Class that contains the dictionary of production to car lists 
class Foo 
{ 
    Dictionary<DateTime, ObservableCollection<Car>> ProductionToCars = new Dictionary<DateTime, ObservableCollection<Car>>(); 

    public void Add(Car c) 
    { 
     _Add(c); 
     // We want to be notified when the car's production changes 
     c.ProductionChanged += this.OnCarProductionChanged; 
    } 
    // This is called when a car's value changes, and moves the car 
    void OnCarProductionChanged(object sender, PropertyValueChange<DateTime> e) 
    { 
     Car c = sender as Car; 
     if (c == null) return; 
     ProductionToCars[e.OldValue].Remove(c); 
     _Add(c); 
    } 
    // this actually places the car in the (currently correct) group 
    private void _Add(Car c) 
    { 
     ObservableCollection<Car> collection; 
     // Find the collection for this car's year 
     if (!ProductionToCars.TryGetValue(c.Production, out collection)) 
     { 
      // if we couldn't find it, create it 
      collection = new ObservableCollection<Car>(); 
      ProductionToCars.Add(c.Production, collection); 
     } 
     // Now place him in the correct collection 
     collection.Add(c); 
    } 

} 
// This class encapsulates the information we'll pass when the property value changes 
public class PropertyValueChange<T> : EventArgs 
{ 
    public T OldValue; 
    public T NewValue; 
    public PropertyValueChange(T oldValue, T newValue) 
    { 
     OldValue = oldValue; 
     NewValue = newValue; 
    } 
} 
1

これは(可能ではない最短のコードを、しかし、理解するのは簡単)動作するはずです:

private static void EnsureValuesAreCoherent(Dictionary<DateTime, ObservableCollection<Car>> param) 
{ 
    List<Car> toMove = new List<Car>(); 
    foreach (KeyValuePair<DateTime, ObservableCollection<Car>> pair in param) 
    { 
     List<Car> toRemove = new List<Car>(); 
     foreach (Car car in pair.Value) 
     { 
      if (car.Production != pair.Key) 
      { 
       toRemove.Add(car); 
      } 
     } 

     foreach (Car car in toRemove) 
     { 
      pair.Value.Remove(car); 
      toMove.Add(car); 
     } 
    } 

    foreach (Car car in toMove) 
    { 
     ObservableCollection<Car> currentCollection; 
     if (param.TryGetValue(car.Production, out currentCollection)) 
     { 
      currentCollection.Add(car); 
     } 
    } 
} 

しかし、IMOそれは、このような辞書のキーの間の依存関係、および辞書のメンバーを持つことが悪い考えです値。

1

この場合、辞書が必要ですか?あなたが特定の生産日のすべての車で操作できるようにしたい場合は、Linqを使用できませんか?あなたが特定の年にすべての車にアクセスすることができ、この方法を使用して

ObservableCollection<Car> cars = new ObservableCollection<Car>(); 
var car1 = new Car() { Model = "Ford", ProductionDate = new DateTime(1997, 01, 01)}); 
var car2 = new Car() { Model = "Chevy", ProductionDate = new DateTime(1997, 01, 01)}); 
var car3 = new Car() { Model = "Ford", ProductionDate = new DateTime(2002, 01, 01)}); 
cars.Add(car1); 
cars.Add(car2); 
cars.Add(car3); 

var carsIn1997 = cars.Where(x => x.ProductionDate.Year == 1997); 
var carsThatAreFords = cars.Where(x => x.Model == "Ford"); 
var groupedCars = cars.GroupBy(x => x.ProductionDate); 

、モデル等...となど動き回るの参照を心配することなく、データを操作する...一般的なGROUPBYチュートリアルについては

here