【问题标题】:C# wpf datagrid with observablecollection. After a user sorts, I can not get the selecctedindex of the observablecollection带有 observablecollection 的 C# wpf 数据网格。用户排序后,我无法获得 observablecollection 的 selectedindex
【发布时间】:2016-09-26 23:26:20
【问题描述】:

我有一个带有可观察集合的数据网格。

 <DataGrid Name="DataGridMemoryTable" AlternatingRowBackground="Beige" Canvas.Left="87" Canvas.Top="30" Width="500" Height="300" RowHeight="20" ColumnWidth="60"
                      SelectionMode="Single" CanUserSortColumns = "False" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="10" ItemsSource="{Binding}" 
                      CurrentCellChanged="DataGridMemoryTableCellChanged" Sorting="DataGridMemoryTable_Sorted"/>

public ObservableCollection<SavedMemorySWL> SavedMemorySWLObservableCollection = new ObservableCollection<SavedMemorySWL>();
    public class SavedMemorySWL : INotifyPropertyChanged
    {
        public String Frequency { get; set; }
        public String Time { get; set; }
        public String Days { get; set; }
        public String ITU_Station { get; set; }
        public String Language_Target_Remarks { get; set; }
        public String Program_Start_Stop { get; set; }
        public String ATAUTOinductor { get; set; }
        public String ATAUTOcapacitor { get; set; }
        public String Antenna { get; set; }
        public Boolean Scan { get; set; }
        public String AT200PCinductor { get; set; }
        public String AT200PCcapacitor { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;
    }

在将行添加到 ObservableCollection 之后...

Global.MW.DataGridMemoryTable.Dispatcher.Invoke(new Action(() =>
            {
                if (Global.MW != null)
                {
                    Global.MW.DataGridMemoryTable.ItemsSource = SavedMemorySWLObservableCollection;
                    Global.MW.DataGridMemoryTable.Items.Refresh();
                    Global.MW.textBoxFileName.Text = memoryRows.FileName;
                }
            }));

所以,问题是如果我允许用​​户对列进行排序,那么稍后我会得到选定的行,它与 ObservableCollection 中的行不匹配。

//int row = DataGridMemoryTable.SelectedIndex;
        int row = DataGridMemoryTable.Items.IndexOf(DataGridMemoryTable.SelectedItem);    //.SelectedIndex;

因此,在排序后,用户单击一个按钮以对他选择的行执行某些操作。如果是顶行,则 selectedindex 为 0。但是 ObservableCollection 中的值没有排序,我对错误的 ObservableCollection 行执行此操作。

我目前的做法是不允许用户进行排序。

有人知道如何将 selectedindex 转换为 ObservableCollection 的索引吗?

【问题讨论】:

  • 当用户对列进行排序时,对 ObservableCollection 进行排序,而不是对 DataGrid 中的数据进行排序。
  • 我很困惑为什么要手动更新数据网格。 ObservableCollections 在它们发生变化时会自动通知绑定到它们的对象。您的 DataGrid 的 Binding 表达式只是 {Binding},这意味着它正在使用父 DataContext - 父 DataContext 是您的 ObservableCollection 吗?应该是 - 如果你这样做了,更新应该会自行解决,这个问题应该会消失。
  • jdweng.那是一个好主意。这是额外的工作/编码,但它是一个可行的解决方案。 "Sorted" 事件通过 DatGridSortingEventArgs e。 e.Column.SortMemberPath 和 e.Column.SortDirection 提供有关用户启动排序的信息。特拉维斯。是的,如果用户对数据网格进行更改,则 ObservableCollection 会自动更改。但是,用户在数据网格上发起的列排序似乎没有反映在 ObservableCollection 中。
  • 特拉维斯,我又看了你的评论。我对 DataContext 一无所知。我实际上有两个可观察的集合,我通过设置 ItemSource 将它们附加到数据网格(在任何给定时间只有一个集合)。它仅在指定 ItemSource 时运行良好。我不确定要为 DataContext 指定什么,但如果它解决了用户排序问题,我会研究它。

标签: c# wpf datagrid


【解决方案1】:

在问这个问题之前我确实搜索过,但经过更多搜索后我找到了答案。

Sort ObservableCollection bound to DataGrid in MVVM

答案是不可能的。

用户对数据网格进行排序永远不会修改 observablecollection 中的下划线数据。没有办法做到这一点。显然微软没有预料到任何人会希望下划线数据也得到排序,所以没有属性设置或方法来实现这一点。

用户排序仅影响 ICollectionView 中的数据。但是,有一种方法可以查看和复制 ICollectionView,如该线程中的第 2 号帖子所示。

    public ICollectionView myCVSWL { get; set; }
internal SavedMemorySWL[] MemoriesSWL = new SavedMemorySWL[MAX_ROWS_SWL];
.
.
.
 Global.MW.DataGridMemoryTable.Dispatcher.Invoke(new Action(() =>
            {
                if (Global.MW != null)
                {
                    myCVSWL = CollectionViewSource.GetDefaultView(SavedMemorySWLObservableCollection);
                    Global.MW.DataGridMemoryTable.ItemsSource = myCVSWL;    // SavedMemorySWLObservableCollection;
                    Global.MW.DataGridMemoryTable.Items.Refresh();
                    Global.MW.textBoxFileName.Text = memoryRows.FileName;
                }
            }));
.
.
.





                        int k = 0;
                    foreach (var item in myCVSWL.OfType<SavedMemorySWL>())
                    {
                        memoryRows.MemoriesSWL[k].Frequency = item.Frequency;
                        memoryRows.MemoriesSWL[k].Time = item.Time;
                        memoryRows.MemoriesSWL[k].Days = item.Days;
                        memoryRows.MemoriesSWL[k].ITU_Station = item.ITU_Station;
                        memoryRows.MemoriesSWL[k].Language_Target_Remarks = item.Language_Target_Remarks;
                        memoryRows.MemoriesSWL[k].Program_Start_Stop = item.Program_Start_Stop;
                        memoryRows.MemoriesSWL[k].ATAUTOinductor = item.ATAUTOinductor;
                        memoryRows.MemoriesSWL[k].ATAUTOcapacitor = item.ATAUTOcapacitor;
                        memoryRows.MemoriesSWL[k].Antenna = item.Antenna;
                        memoryRows.MemoriesSWL[k].Scan = item.Scan;
                        memoryRows.MemoriesSWL[k].AT200PCinductor = item.AT200PCinductor;
                        memoryRows.MemoriesSWL[k].AT200PCcapacitor = item.AT200PCcapacitor;
                        k++;
                    }

感谢那些对此提出一些想法并试图提供帮助的人。

问候, 霍华德

【讨论】:

  • 我已经取消了所有这些更改并禁用了数据网格列排序,因为 ICollectionView 似乎不支持 INotifyPropertyChanged。我发现使用表格是一个同时使用 Java/Swing 和 VS/WPF 的 PITA。
猜你喜欢
  • 1970-01-01
  • 2011-01-25
  • 2010-11-03
  • 1970-01-01
  • 2015-12-29
  • 1970-01-01
  • 1970-01-01
  • 2021-07-04
  • 1970-01-01
相关资源
最近更新 更多