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}