将元素从一个字典移动到另一个字典

时间:2012-02-01 15:48:41

标签: c# c#-4.0 dictionary

我有一对很少的词典

Dictionary<DateTime, ObservableCollection<Car>>

我正在改变Car的制作年份,因为KeyDateTime)是一年,我需要从{{1}移动Car新年到KeyValuePair新年。

所以例如,我有两对:

KeyValuePair

1.1.1997 {Car1,Car2}
1.1.1998 {Car3}

我需要

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

实现这一目标的最简单方法是什么?

3 个答案:

答案 0 :(得分:2)

您似乎可能希望对此数据使用分组视图,但这里是一个解决所述问题的代码解决方案。如果您计划为多个属性执行此操作,我建议您从DependencyObject继承Car或从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 :(得分: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在字典的键和字典值的成员之间存在这种依赖关系是个坏主意。

答案 2 :(得分: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