Index: Core/Common/src/Core.Common.Controls.Swf/Table/TableView.cs =================================================================== diff -u -r10b304d4b5cb2283801cdb16204baf2a42ab5967 -r9f917802e4ebd3c4c6681e7f42198d6e758cafed --- Core/Common/src/Core.Common.Controls.Swf/Table/TableView.cs (.../TableView.cs) (revision 10b304d4b5cb2283801cdb16204baf2a42ab5967) +++ Core/Common/src/Core.Common.Controls.Swf/Table/TableView.cs (.../TableView.cs) (revision 9f917802e4ebd3c4c6681e7f42198d6e758cafed) @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.ComponentModel; using System.Data; using System.Drawing; @@ -13,7 +14,6 @@ using Core.Common.Controls.Swf.Table.Validation; using Core.Common.Utils; using Core.Common.Utils.Collections; -using Core.Common.Utils.Collections.Generic; using Core.Common.Utils.Reflection; using DevExpress.Data; using DevExpress.Utils; @@ -47,9 +47,9 @@ } private static readonly ILog Log = LogManager.GetLogger(typeof(TableView)); - private readonly EventedList selectedCells; + private readonly ICollection selectedCells; private readonly TableViewValidator tableViewValidator; - private readonly EventedList columns; + private readonly List columns; private bool isPasting; private bool isSelectionChanging; private bool updatingSelection; @@ -66,9 +66,9 @@ { InitializeComponent(); - columns = new EventedList(); + columns = new List(); ColumnMenuItems = new List(); - selectedCells = new EventedList(); + selectedCells = new HashSet(); tableViewValidator = new TableViewValidator(this); PasteController = new TableViewPasteController(this) { @@ -99,7 +99,7 @@ // the build-in export to file method depends on a devexpress dll we haven't included so far using (var writer = new StreamWriter(fileName)) { - var visibleColumns = Columns.Where(c => c.Visible).OrderBy(c => c.DisplayIndex); + var visibleColumns = columns.Where(c => c.Visible).OrderBy(c => c.DisplayIndex); var lastColumn = visibleColumns.Last(); foreach (var visibleColumn in visibleColumns) @@ -121,7 +121,7 @@ for (int y = 0; y < shownColumns.Length; y++) { writer.Write(GetCellDisplayText(x, shownColumns[y])); - if (y != Columns.Count - 1) + if (y != columns.Count - 1) { writer.Write(delimiter); } @@ -159,9 +159,9 @@ dxGridControl.Dispose(); } - if (Columns != null) + if (columns != null) { - foreach (var column in Columns) + foreach (var column in columns) { column.Dispose(); } @@ -281,17 +281,17 @@ private TableViewColumn GetColumnByDxColumn(GridColumn dxGridColumn) { - return Columns.FirstOrDefault(c => c.AbsoluteIndex == dxGridColumn.AbsoluteIndex); + return columns.FirstOrDefault(c => c.AbsoluteIndex == dxGridColumn.AbsoluteIndex); } private void BestFitColumnsWithOnlyFirstWordOfHeader() { - var oldHeaders = Columns.ToDictionary(c => c, c => c.Caption); + var oldHeaders = columns.ToDictionary(c => c, c => c.Caption); dxGridView.BeginUpdate(); try { - foreach (var column in Columns) + foreach (var column in columns) { string caption = column.Caption; @@ -318,7 +318,7 @@ dxGridView.BestFitColumns(); //restore the original columns - foreach (var column in Columns) + foreach (var column in columns) { column.Caption = oldHeaders[column]; } @@ -341,7 +341,7 @@ var selectedCell = selectedCells.FirstOrDefault(c => c.Column == GetColumnByDisplayIndex(x) && c.RowIndex == y); if (selectedCell != null) { - selectedCells.Remove(selectedCell); + DeselectCell(selectedCell); cellsDeselected = true; } } @@ -354,7 +354,7 @@ private void AddEnumCellEditors() { - foreach (var column in Columns.Where(c => c.ColumnType.IsEnum && c.Editor == null)) + foreach (var column in columns.Where(c => c.ColumnType.IsEnum && c.Editor == null)) { column.Editor = new ComboBoxTypeEditor { @@ -365,43 +365,11 @@ } } - private void ColumnsOnCollectionChanged(object sender, NotifyCollectionChangingEventArgs e) - { - if (e.Action == NotifyCollectionChangeAction.Remove && dxGridView.Columns.Count > e.Index) - { - dxGridView.Columns.RemoveAt(e.Index); - } - } - private static void CopyPasteControllerPasteFailed(object sender, EventArgs e) { MessageBox.Show(e.Value); } - private void SelectedCellsCollectionChanged(object sender, NotifyCollectionChangingEventArgs e) - { - if (updatingSelection) - { - return; - } - - var cell = (TableViewCell) e.Item; - - var gridColumn = GetDxColumnByDisplayIndex(cell.Column.DisplayIndex); - - switch (e.Action) - { - case NotifyCollectionChangeAction.Add: - dxGridView.SelectCell(cell.RowIndex, gridColumn); - break; - case NotifyCollectionChangeAction.Remove: - dxGridView.UnselectCell(cell.RowIndex, gridColumn); - break; - default: - throw new NotSupportedException(string.Format(Resources.TableView_SelectedCellsCollectionChanged_Action_0_is_not_supported_by_the_TableView, e.Action)); - } - } - private void BindingListListChanged(object sender, ListChangedEventArgs e) { if (!AutoGenerateColumns || e.ListChangedType != ListChangedType.PropertyDescriptorChanged || e.PropertyDescriptor == null) @@ -559,13 +527,13 @@ private bool GetSelectionIsReadonly() { //no selection use tableview readonly - if (SelectedCells.Count == 0) + if (selectedCells.Count == 0) { return ReadOnly; } //A selection is readonly if ALL cells are readonly (otherwise i can change the not readonly part) - return SelectedCells.All(cell => CellIsReadOnly(cell.RowIndex, cell.Column)); + return selectedCells.All(cell => CellIsReadOnly(cell.RowIndex, cell.Column)); } private void UpdateSelectionFromGridControl() @@ -577,12 +545,13 @@ updatingSelection = true; - selectedCells.Clear(); + ClearSelectedCells(); var gridViewSelectedCells = dxGridView.GetSelectedCells(); foreach (var cell in gridViewSelectedCells) { - selectedCells.Add(new TableViewCell(cell.RowHandle, GetColumnByDxColumn(cell.Column))); + var tableViewCell = new TableViewCell(cell.RowHandle, GetColumnByDxColumn(cell.Column)); + SelectCell(tableViewCell); } if (!IsEditing && !isPasting) @@ -610,18 +579,15 @@ return; } - columns.CollectionChanged -= ColumnsOnCollectionChanged; columns.Clear(); foreach (GridColumn dxColumn in dxGridView.Columns) { - Columns.Add(new TableViewColumn(dxGridView, dxGridControl, dxColumn, this, false) + columns.Add(new TableViewColumn(dxGridView, dxGridControl, dxColumn, this, false) { SortingAllowed = AllowColumnSorting }); } - - columns.CollectionChanged += ColumnsOnCollectionChanged; } private void ShowEditorIfRowSelect() @@ -634,7 +600,7 @@ private GridColumn GetDxColumnByDisplayIndex(int displayIndex) { - return dxGridView.Columns[Columns.First(c => c.DisplayIndex == displayIndex).AbsoluteIndex]; + return dxGridView.Columns[columns.First(c => c.DisplayIndex == displayIndex).AbsoluteIndex]; } private void UpdateColumnHeaderMenu(GridMenuEventArgs e, TableViewColumn viewColumn) @@ -871,7 +837,7 @@ } allowColumnSorting = value; - foreach (var column in Columns) + foreach (var column in columns) { column.SortingAllowed = allowColumnSorting; } @@ -1169,7 +1135,7 @@ public ValidationExceptionMode ExceptionMode { get; set; } [Browsable(false)] - public IList SelectedCells + public IEnumerable SelectedCells { get { @@ -1181,11 +1147,11 @@ // when something changes in columns designers becomes mad because of broken resx files [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - public IList Columns + public ReadOnlyCollection Columns { get { - return columns; + return columns.AsReadOnly(); } } @@ -1285,11 +1251,11 @@ { get { - return Columns.OfType().Any(c => c.FilteringAllowed); + return columns.OfType().Any(c => c.FilteringAllowed); } set { - foreach (var column in Columns.OfType()) + foreach (var column in columns.OfType()) { column.FilteringAllowed = value; } @@ -1340,7 +1306,7 @@ /// public void BestFitColumns(bool useOnlyFirstWordOfHeader = false) { - dxGridView.BestFitMaxRowCount = Columns.Count > 50 ? 10 : 50; + dxGridView.BestFitMaxRowCount = columns.Count > 50 ? 10 : 50; if (useOnlyFirstWordOfHeader) { @@ -1388,7 +1354,7 @@ public TableViewColumn GetColumnByName(string columnName) { - return Columns.FirstOrDefault(c => c.Name == columnName); + return columns.FirstOrDefault(c => c.Name == columnName); } public void SelectRow(int index, bool clearPreviousSelection = true) @@ -1593,20 +1559,48 @@ if (clearOldSelection) { - selectedCells.Clear(); + ClearSelectedCells(); } for (int y = top; y <= bottom; y++) { for (int x = left; x <= right; x++) { - selectedCells.Add(new TableViewCell(y, GetColumnByDisplayIndex(x))); + var tableViewCell = new TableViewCell(y, GetColumnByDisplayIndex(x)); + SelectCell(tableViewCell); } } dxGridView.EndSelection(); //dxGridControl.ResumeLayout(); } + private void SelectCell(TableViewCell cell) + { + if (!updatingSelection) + { + selectedCells.Add(cell); + var gridColumn = GetDxColumnByDisplayIndex(cell.Column.DisplayIndex); + dxGridView.SelectCell(cell.RowIndex, gridColumn); + } + } + + private void ClearSelectedCells() + { + foreach (var cell in selectedCells.ToArray()) + { + DeselectCell(cell); + } + } + + private void DeselectCell(TableViewCell cell) + { + if (!updatingSelection && selectedCells.Remove(cell)) + { + var gridColumn = GetDxColumnByDisplayIndex(cell.Column.DisplayIndex); + dxGridView.UnselectCell(cell.RowIndex, gridColumn); + } + } + /// /// Pastes clipboard contens into current selection /// @@ -1710,8 +1704,8 @@ } //delete rows in case entire rows are selected - var groupBy = SelectedCells.GroupBy(c => c.RowIndex); - var count = Columns.Count(c => c.Visible); + var groupBy = selectedCells.GroupBy(c => c.RowIndex); + var count = columns.Count(c => c.Visible); if (AllowDeleteRow && (RowSelect || groupBy.All(g => g.Count() == count))) { if (RowDeleteHandler == null || !RowDeleteHandler()) @@ -1721,7 +1715,7 @@ return; } - var selectedGridCells = SelectedCells.ToList(); + var selectedGridCells = selectedCells.ToList(); foreach (var c in selectedGridCells) { var defaultValue = c.Column.DefaultValue ?? @@ -1746,9 +1740,31 @@ column.DisplayFormat = displayFormat; } - Columns.Add(column); + columns.Add(column); } + public void ClearColumns() + { + dxGridView.Columns.Clear(); + columns.Clear(); + } + + public void Remove(TableViewColumn column) + { + if (columns.Remove(column)) + { + dxGridView.Columns.Remove(column.DxColumn); + } + } + + public void RemoveAllWhere(Func whereClause) + { + foreach (var tableViewColumn in columns.Where(whereClause).ToArray()) + { + Remove(tableViewColumn); + } + } + /// /// Adds an unbound column to the table. (Use to set values for the column) /// @@ -1760,7 +1776,7 @@ { var unbColumn = dxGridView.Columns.AddField(columnName); var column = new TableViewColumn(dxGridView, dxGridControl, unbColumn, this, true); - Columns.Add(column); + columns.Add(column); unbColumn.VisibleIndex = index != -1 ? index : dxGridView.Columns.Count; @@ -1827,7 +1843,7 @@ /// internal bool IsSorted() { - return Columns.Any(c => c.SortOrder != SortOrder.None); + return columns.Any(c => c.SortOrder != SortOrder.None); } internal TableViewCell GetFocusedCell() @@ -1883,7 +1899,7 @@ internal TableViewColumn GetColumnByDisplayIndex(int i) { - return Columns.FirstOrDefault(c => c.DisplayIndex == i); + return columns.FirstOrDefault(c => c.DisplayIndex == i); } #endregion @@ -1997,7 +2013,7 @@ return; } - var selectedColumn = Columns.OfType() + var selectedColumn = columns.OfType() .FirstOrDefault(c => c.DxColumn == dxGridView.FocusedColumn); ColumnFilterChanged(sender, new EventArgs(selectedColumn)); @@ -2034,7 +2050,7 @@ if (e.HitInfo.Column != null) //on a column { - tableViewColumn = Columns.FirstOrDefault(c => c.Caption == e.HitInfo.Column.GetTextCaption()); + tableViewColumn = columns.FirstOrDefault(c => c.Caption == e.HitInfo.Column.GetTextCaption()); } UpdateColumnHeaderMenu(e, tableViewColumn); @@ -2499,14 +2515,12 @@ // selection events dxGridView.SelectionChanged += DxGridViewSelectionChanged; - selectedCells.CollectionChanged += SelectedCellsCollectionChanged; dxGridView.ShowGridMenu += DxGridViewShowDxGridMenu; dxGridView.ValidateRow += tableViewValidator.OnValidateRow; dxGridControl.EmbeddedNavigator.ButtonClick += EmbeddedNavigatorButtonClick; PasteController.PasteFailed += CopyPasteControllerPasteFailed; - columns.CollectionChanged += ColumnsOnCollectionChanged; } #endregion Index: Core/Common/src/Core.Common.Controls.Swf/Table/TableViewPasteController.cs =================================================================== diff -u -rc34a894787b4281dd3770eacd67436c55575d006 -r9f917802e4ebd3c4c6681e7f42198d6e758cafed --- Core/Common/src/Core.Common.Controls.Swf/Table/TableViewPasteController.cs (.../TableViewPasteController.cs) (revision c34a894787b4281dd3770eacd67436c55575d006) +++ Core/Common/src/Core.Common.Controls.Swf/Table/TableViewPasteController.cs (.../TableViewPasteController.cs) (revision 9f917802e4ebd3c4c6681e7f42198d6e758cafed) @@ -143,7 +143,7 @@ return GetRowSelectSelection(); } - var cells = TableView.SelectedCells; + var cells = TableView.SelectedCells.ToList(); if (cells.Count == 0) { //base selection on focused cell Index: Core/Common/src/Core.Common.Utils/Collections/Generic/EventedList.cs =================================================================== diff -u -ref35125104cc8b0201f9c961049cc6c8a30fb74d -r9f917802e4ebd3c4c6681e7f42198d6e758cafed --- Core/Common/src/Core.Common.Utils/Collections/Generic/EventedList.cs (.../EventedList.cs) (revision ef35125104cc8b0201f9c961049cc6c8a30fb74d) +++ Core/Common/src/Core.Common.Utils/Collections/Generic/EventedList.cs (.../EventedList.cs) (revision 9f917802e4ebd3c4c6681e7f42198d6e758cafed) @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.ComponentModel; using System.Data; -using log4net; namespace Core.Common.Utils.Collections.Generic { @@ -19,8 +18,6 @@ public event NotifyCollectionChangedEventHandler CollectionChanged; public event PropertyChangingEventHandler PropertyChanging; public event PropertyChangedEventHandler PropertyChanged; - private static readonly ILog eventsLog = LogManager.GetLogger("Events"); - // TODO: make it work on Ranges and send events on ranges /// /// The underlying storage @@ -31,7 +28,6 @@ private PropertyChangingEventHandler Item_PropertyChangingDelegate; private PropertyChangedEventHandler Item_PropertyChangedDelegate; private NotifyCollectionChangedEventHandler Item_CollectionChangedDelegate; - public bool HasParent { get; set; } #region Constructors Index: Core/Common/test/Core.Common.Controls.Swf.Test/Table/TableViewPasteControllerTest.cs =================================================================== diff -u -re29972e3a754b192d4f792639e599eb193e6ea8d -r9f917802e4ebd3c4c6681e7f42198d6e758cafed --- Core/Common/test/Core.Common.Controls.Swf.Test/Table/TableViewPasteControllerTest.cs (.../TableViewPasteControllerTest.cs) (revision e29972e3a754b192d4f792639e599eb193e6ea8d) +++ Core/Common/test/Core.Common.Controls.Swf.Test/Table/TableViewPasteControllerTest.cs (.../TableViewPasteControllerTest.cs) (revision 9f917802e4ebd3c4c6681e7f42198d6e758cafed) @@ -226,8 +226,8 @@ Data = list }; //make a diagonal selection - tableView.SelectedCells.Add(new TableViewCell(0, tableView.Columns.FirstOrDefault(c => c.DisplayIndex == 0))); - tableView.SelectedCells.Add(new TableViewCell(1, tableView.Columns.FirstOrDefault(c => c.DisplayIndex == 1))); + tableView.SelectCells(0, 0, 0, 0); + tableView.SelectCells(1, 1, 1, 1, false); var tableViewCopyPasteController = new TableViewPasteController(tableView); int callCount = 0; Index: Core/Common/test/Core.Common.Controls.Swf.Test/Table/TableViewTest.cs =================================================================== diff -u -r00561a8c93e3a28b5f0e078fa7219a65408e931b -r9f917802e4ebd3c4c6681e7f42198d6e758cafed --- Core/Common/test/Core.Common.Controls.Swf.Test/Table/TableViewTest.cs (.../TableViewTest.cs) (revision 00561a8c93e3a28b5f0e078fa7219a65408e931b) +++ Core/Common/test/Core.Common.Controls.Swf.Test/Table/TableViewTest.cs (.../TableViewTest.cs) (revision 9f917802e4ebd3c4c6681e7f42198d6e758cafed) @@ -397,7 +397,7 @@ tableView.SelectCells(1, 0, 2, 1); - Assert.AreEqual(4, tableView.SelectedCells.Count); + Assert.AreEqual(4, tableView.SelectedCells.Count()); tableView.CopySelectionToClipboard(); @@ -446,7 +446,7 @@ tableView.SelectCells(1, 0, 2, 1); - Assert.AreEqual(4, tableView.SelectedCells.Count); + Assert.AreEqual(4, tableView.SelectedCells.Count()); tableView.CopySelectionToClipboard(); @@ -494,7 +494,7 @@ tableView.SelectCells(0, 0, 2, 1); - Assert.AreEqual(6, tableView.SelectedCells.Count); + Assert.AreEqual(6, tableView.SelectedCells.Count()); tableView.CopySelectionToClipboard(); @@ -883,7 +883,7 @@ tableView.SelectCells(5, 0, 9, 1); //check the bottom cells are all selected - Assert.AreEqual(10, tableView.SelectedCells.Count); + Assert.AreEqual(10, tableView.SelectedCells.Count()); } [Test] Index: Core/Plugins/src/Core.Plugins.SharpMapGis.Gui/Forms/VectorLayerAttributeTableView.cs =================================================================== diff -u -r1ced28e1822cbe82e3adbab152aa591119f17a9b -r9f917802e4ebd3c4c6681e7f42198d6e758cafed --- Core/Plugins/src/Core.Plugins.SharpMapGis.Gui/Forms/VectorLayerAttributeTableView.cs (.../VectorLayerAttributeTableView.cs) (revision 1ced28e1822cbe82e3adbab152aa591119f17a9b) +++ Core/Plugins/src/Core.Plugins.SharpMapGis.Gui/Forms/VectorLayerAttributeTableView.cs (.../VectorLayerAttributeTableView.cs) (revision 9f917802e4ebd3c4c6681e7f42198d6e758cafed) @@ -295,7 +295,7 @@ private void ConfigureStaticAttributeColumns() { - TableView.Columns.Clear(); + TableView.ClearColumns(); TableView.AutoGenerateColumns = false; if (createFeatureRowObject == null) @@ -345,7 +345,7 @@ private void ConfigureDynamicAttributeColumns() { - TableView.Columns.RemoveAllWhere(c => c.IsUnbound); + TableView.RemoveAllWhere(c => c.IsUnbound); var attributes = layer.DataSource.Features.Cast() .Where(f => f.Attributes != null).SelectMany(feature => feature.Attributes.Keys) @@ -494,7 +494,7 @@ } column.Visible = false; - TableView.Columns.Remove(column); + TableView.Remove(column); var attributeName = column.Name;