2012-02-01 89 views
0

我有几双从一本词典移动元素到另一个

Dictionary<DateTime, ObservableCollection<Car>> 

,我改变生产Car的一年,因为KeyDateTime)词典是一年,我需要移动这CarKeyValuePair与旧的一年到KeyValuePair与新的一年。

因此,例如,我有两个对:

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

不确定有任何* easy *方法可以做到这一点。您可能需要重新考虑使用生产年份的'DateTime'作为'Dictionary'中的'Key'。如果这是一个数据库,你会引入一个非常讨厌的函数依赖。 – Yuck 2012-02-01 15:55:25

+0

我知道存在代码异味,但我没有太多时间来重构这个。我需要使用该代码。 – user278618 2012-02-01 15:56:43

+0

您是否有权访问代码区中的'Dictionary >',在这个代码区中,您要提取个别'Car'来修改其“Production”值? – Yuck 2012-02-01 15:59:40

回答

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

相关问题