编辑一个数据网格会改变另一个

时间:2012-07-13 16:25:54

标签: wpf data-binding datagrid wpfdatagrid

两个WPF数据网格有一个奇怪的问题,它们绑定了ObservableCollections。

这是我的XAML:

<Grid Name="gridShifts">
<Grid.ColumnDefinitions>
    <ColumnDefinition/>
    <ColumnDefinition/>
</Grid.ColumnDefinitions>
    <Custom:C1DataGrid Name="dgShift1"
                       HorizontalAlignment="Left" AutoGenerateColumns="False" CanUserAddRows="False" CanUserRemoveRows="False" CanUserReorderColumns="False" Grid.Column="0">
        <Custom:C1DataGrid.Columns>
            <Custom:DataGridTextColumn Binding="{Binding Path=Type, Mode=TwoWay}" IsReadOnly="True"  Header="Work Center"/>
            <Custom:DataGridTextColumn Binding="{Binding Path=RegularSkill, Mode=TwoWay }" Header="Personnel"/>
        </Custom:C1DataGrid.Columns>
    </Custom:C1DataGrid>
    <Custom:C1DataGrid Name="dgShift2"
                       HorizontalAlignment="Left" AutoGenerateColumns="False" CanUserAddRows="False" CanUserRemoveRows="False" CanUserReorderColumns="False" Grid.Column="1">
        <Custom:C1DataGrid.Columns>
            <Custom:DataGridTextColumn Binding="{Binding Path=Type, Mode=TwoWay}" IsReadOnly="True"  Header="Work Center"/>
            <Custom:DataGridTextColumn Binding="{Binding Path=RegularSkill, Mode=TwoWay }" Header="Personnel"/>
        </Custom:C1DataGrid.Columns>
    </Custom:C1DataGrid>
</Grid>

这是我的代码背后:

public partial class MainWindow : Window
{
    AMMData.Manpower mp = new AMMData.Manpower();

    public MainWindow()
    {
        InitializeComponent();

        gridShifts.DataContext = mp;
        dgShift1.ItemsSource = mp.WorkShifts[0].WCList;
        dgShift2.ItemsSource = mp.WorkShifts[1].WCList;

    }
}
编辑:这是人力类:

public enum WCSpecialty
{
    Indirect,
    Airframes,
    AviationLifeSupport,
    PeriodicMaintenance,
    Electronics,
    Electrical_Instruments,
    Armaments,
    Reconnaissance,
    Line,
    NA
}

public class Manpower : ComponentDataWrapper
{
    #region Private Properties

    private ObservableCollection<WCCollection> workShifts = new ObservableCollection<WCCollection>();

    #endregion

    #region Public Properties

    public ObservableCollection<WCCollection> WorkShifts { set { workShifts = value; NotifyPropertyChanged("WorkShifts"); } get { return workShifts; } }

    #endregion


    public Manpower()
    {
        Name = "New Work Center Structure";
        Description = "New Work Center Personnel Description";
        LastChanged = System.DateTime.Now;

        var wcc1 = new AMMData.WCCollection();
        var wcc2 = new AMMData.WCCollection();

        var wc1 = new AMMData.WorkCenter { Type = AMMData.WCSpecialty.Indirect, RegularSkill = 0, MedSkill = 999, HighSkill = 999 };
        var wc2 = new AMMData.WorkCenter { Type = AMMData.WCSpecialty.Airframes, RegularSkill = 0, MedSkill = 999, HighSkill = 999 };
        var wc3 = new AMMData.WorkCenter { Type = AMMData.WCSpecialty.AviationLifeSupport, RegularSkill = 0, MedSkill = 999, HighSkill = 999 };
        var wc4 = new AMMData.WorkCenter { Type = AMMData.WCSpecialty.PeriodicMaintenance, RegularSkill = 0, MedSkill = 999, HighSkill = 999 };
        var wc5 = new AMMData.WorkCenter { Type = AMMData.WCSpecialty.Electronics, RegularSkill = 0, MedSkill = 999, HighSkill = 999 };
        var wc6 = new AMMData.WorkCenter { Type = AMMData.WCSpecialty.Electrical_Instruments, RegularSkill = 0, MedSkill = 999, HighSkill = 999 };
        var wc7 = new AMMData.WorkCenter { Type = AMMData.WCSpecialty.Armaments, RegularSkill = 0, MedSkill = 999, HighSkill = 999 };
        var wc8 = new AMMData.WorkCenter { Type = AMMData.WCSpecialty.Reconnaissance, RegularSkill = 0, MedSkill = 999, HighSkill = 999 };
        var wc9 = new AMMData.WorkCenter { Type = AMMData.WCSpecialty.Line, RegularSkill = 0, MedSkill = 999, HighSkill = 999 };
        var wc10 = new AMMData.WorkCenter { Type = AMMData.WCSpecialty.NA, RegularSkill = 0, MedSkill = 999, HighSkill = 999 };

        wcc1.WCList.Add(wc1);
        wcc1.WCList.Add(wc2);
        wcc1.WCList.Add(wc3);
        wcc1.WCList.Add(wc4);
        wcc1.WCList.Add(wc5);
        wcc1.WCList.Add(wc6);
        wcc1.WCList.Add(wc7);
        wcc1.WCList.Add(wc8);
        wcc1.WCList.Add(wc9);
        wcc1.WCList.Add(wc10);

        wcc2.WCList.Add(wc1);
        wcc2.WCList.Add(wc2);
        wcc2.WCList.Add(wc3);
        wcc2.WCList.Add(wc4);
        wcc2.WCList.Add(wc5);
        wcc2.WCList.Add(wc6);
        wcc2.WCList.Add(wc7);
        wcc2.WCList.Add(wc8);
        wcc2.WCList.Add(wc9);
        wcc2.WCList.Add(wc10);

        WorkShifts.Add(wcc1);
        WorkShifts.Add(wcc2);

    }
}

public class WCCollection : ComponentDataWrapper
{
    private ObservableCollection<WorkCenter> wcList = new ObservableCollection<WorkCenter>();

    public ObservableCollection<WorkCenter> WCList { set { wcList = value; NotifyPropertyChanged("WCList"); } get { return wcList; } }
}

    public class WorkCenter : ComponentDataWrapper
{
    #region private

    private WCSpecialty type;
    private int regularSkill;
    private int highSkill;
    private int medSkill;

    #endregion

    #region public

    public WCSpecialty Type { set { type = value; NotifyPropertyChanged("Type"); } get { return type; } }
    public int RegularSkill { set { regularSkill = value; NotifyPropertyChanged("RegularSkill"); } get { return regularSkill; } }
    public int HighSkill { set { highSkill = value; NotifyPropertyChanged("HighSkill"); } get { return highSkill; } }
    public int MedSkill { set { medSkill = value; NotifyPropertyChanged("MedSkill"); } get { return medSkill; } }

    public int RegularWholePeople { get { return regularSkill / 10; } }

    #endregion
}

我的问题是,当我编辑一个数据网格时,其他的值也会发生变化。我已经尝试将两个网格的datacontext设置为各自的ObservableCollections,但同样的事情发生了。我觉得我对WPF数据绑定在这一点上的工作原理有点熟悉,但我对这个问题感到很难过。谢谢你的帮助。

2 个答案:

答案 0 :(得分:2)

您的商品似乎是通过引用添加到ObservableCollections,而不是按值添加。

这意味着两个集合都包含对内存中同一对象的引用,因此更新一个集合中的对象实际上是更新单个对象引用,这也导致其他集合也更新

答案 1 :(得分:0)

您已将mp对象传递给DataGrid。因此,无需使用后面的代码传递集合。

更新您的绑定:

<Custom:DataGridTextColumn Binding="{Binding ElementName=gridShifts, Path=DataContex.WorkShifts[0].WCList Mode=TwoWay}" IsReadOnly="True"  Header="Work Center"/>

您还应该为您的数据源使用CollectionViewSource个实例,如WPF’s CollectionViewSource所示。这是一个更清洁的设计,可能会带来好处。