main
  1using System.Collections;
  2using System.Linq;
  3using System.Windows;
  4using System.Windows.Controls;
  5using System.Windows.Data;
  6using System.Windows.Input;
  7
  8namespace solidware.financials.windows.ui.views.controls
  9{
 10    public class SmartGrid : DataGrid
 11    {
 12        static SmartGrid()
 13        {
 14            IsReadOnlyProperty.OverrideMetadata(typeof (SmartGrid), new FrameworkPropertyMetadata((o, e) => ((SmartGrid) o).ConfigureColumns()));
 15            CommandManager.RegisterClassCommandBinding(typeof (SmartGrid), new CommandBinding(ApplicationCommands.Paste, (o, e) => ((SmartGrid) o).OnExecutedPaste()));
 16        }
 17
 18        public SmartGrid()
 19        {
 20            SelectionUnit = DataGridSelectionUnit.CellOrRowHeader;
 21            ContextMenu = new ContextMenu
 22                          {
 23                              Items =
 24                                  {
 25                                      new MenuItem {Command = ApplicationCommands.Copy},
 26                                      new MenuItem {Command = ApplicationCommands.Paste}
 27                                  }
 28                          };
 29        }
 30
 31        void ConfigureColumns()
 32        {
 33            foreach (var column in Columns)
 34            {
 35                column.IsReadOnly = IsReadOnly;
 36            }
 37        }
 38
 39        protected override void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
 40        {
 41            base.OnItemsSourceChanged(oldValue, newValue);
 42            if (newValue == null) return;
 43
 44            var enumerator = newValue.GetEnumerator();
 45            if (!enumerator.MoveNext()) return;
 46
 47            var firstRow = enumerator.Current as Row;
 48            if (firstRow == null) return;
 49
 50            AutoGenerateColumns = false;
 51            Columns.Clear();
 52            foreach (var pair in firstRow)
 53            {
 54                Columns.Add(new ExtendedTextColumn
 55                            {
 56                                Header = pair.Key,
 57                                Binding = new Binding("[" + pair.Key + "].Value")
 58                            });
 59            }
 60            ConfigureColumns();
 61        }
 62
 63        protected virtual void OnExecutedPaste()
 64        {
 65            OnBeginningEdit(new DataGridBeginningEditEventArgs(Columns.First(), new DataGridRow(), new RoutedEventArgs()));
 66            var rowData = ClipboardHelper.ParseClipboardData();
 67
 68            var minColumnDisplayIndex = SelectedCells.Min(x => x.Column.DisplayIndex);
 69            var maxColumnDisplayIndex = SelectedCells.Max(x => x.Column.DisplayIndex);
 70            var minRowIndex = SelectedCells.Min(y => Items.IndexOf(y.Item));
 71            var maxRowIndex = SelectedCells.Max(y => Items.IndexOf(y.Item));
 72
 73            // If single cell select, then use as a starting cell rather than limiting the paste
 74            if (minColumnDisplayIndex == maxColumnDisplayIndex && minRowIndex == maxRowIndex)
 75            {
 76                maxColumnDisplayIndex = Columns.Count - 1;
 77                maxRowIndex = Items.Count - 1;
 78            }
 79
 80            var rowDataIndex = 0;
 81            for (var i = minRowIndex; i <= maxRowIndex && rowDataIndex <= rowData.Count() - 1; i++, rowDataIndex++)
 82            {
 83                var columnDataIndex = 0;
 84                for (var j = minColumnDisplayIndex; j <= maxColumnDisplayIndex && columnDataIndex <= rowData[rowDataIndex].Length - 1; j++, columnDataIndex++)
 85                {
 86                    var column = ColumnFromDisplayIndex(j);
 87                    if (column.IsReadOnly) continue;
 88                    column.OnPastingCellClipboardContent(Items[i], rowData[rowDataIndex][columnDataIndex]);
 89                }
 90            }
 91        }
 92
 93        protected override void OnKeyUp(KeyEventArgs e)
 94        {
 95            switch (e.Key)
 96            {
 97                case Key.Delete:
 98                    foreach (var cell in SelectedCells.Where(x => !x.Column.IsReadOnly))
 99                    {
100                        // N.B. Passing in an integer value of zero results in the Gas (MCF) column updating,
101                        //      but no other column updating. Using a string "0" results in all values
102                        //      updating properly. Very odd behaviour, but insufficient time to investigate why.
103                        cell.Column.OnPastingCellClipboardContent(cell.Item, "0");
104                    }
105                    OnBeginningEdit(new DataGridBeginningEditEventArgs(Columns.First(), new DataGridRow(), new RoutedEventArgs()));
106                    break;
107                case Key.Enter:
108                    OnBeginningEdit(new DataGridBeginningEditEventArgs(Columns.First(), new DataGridRow(), new RoutedEventArgs()));
109                    break;
110                default:
111                    base.OnKeyUp(e);
112                    break;
113            }
114        }
115    }
116}