/// <summary> /// Gets the data context for the specified cell. /// </summary> /// <param name="cell">The cell.</param> /// <returns>The context object.</returns> public object GetDataContext(CellRef cell) { var pd = this.GetPropertyDefinition(cell); var item = this.GetItem(cell); return(pd.PropertyName != null ? item : this.Owner.ItemsSource); }
/// <summary> /// Gets the value in the specified cell. /// </summary> /// <param name="cell">The cell.</param> /// <returns>The value</returns> public virtual object GetCellValue(CellRef cell) { if (cell.Column < 0 || cell.Column >= this.Owner.Columns || cell.Row < 0 || cell.Row >= this.Owner.Rows) { return(null); } var item = this.GetItem(cell); if (item != null) { var pd = this.GetPropertyDefinition(cell); if (pd != null) { var descriptor = this.GetPropertyDescriptor(pd, item, null); if (descriptor != null) { return(descriptor.GetValue(item)); } return(item); } } return(null); }
/// <summary> /// Gets the type of the property in the specified cell. /// </summary> /// <param name="cell">The cell.</param> /// <returns>The type of the property.</returns> public virtual Type GetPropertyType(CellRef cell) { var definition = this.GetPropertyDefinition(cell); var currentValue = this.GetCellValue(cell); return(this.GetPropertyType(definition, cell, currentValue)); }
/// <summary> /// Gets the item in cell. /// </summary> /// <param name="cell">The cell reference.</param> /// <returns> /// The <see cref="object" />. /// </returns> public override object GetItem(CellRef cell) { var list = this.ItemsSource; int rowIndex = cell.Row; int columnIndex = cell.Column; if (list == null || rowIndex < 0 || columnIndex < 0) { return(null); } if (rowIndex >= list.Count) { return(null); } var row = list[rowIndex] as IList; if (row == null || columnIndex >= row.Count) { return(null); } return(((IList)list[rowIndex])[columnIndex]); }
protected override void ApplyProperties(CellDefinition cd, DataGrid owner, CellRef cell, PropertyDefinition pd, object item) { base.ApplyProperties(cd, owner, cell, pd, item); cd.IsEnabledBindingSource = this.isItemEnabledSource; cd.IsEnabledBindingParameter = "yes"; cd.IsEnabledBindingPath = owner.Operator.GetBindingPath(owner, cell); }
/// <summary> /// Gets the item index for the specified cell. /// </summary> /// <param name="owner">The owner.</param> /// <param name="cell">The cell.</param> /// <returns> /// The get item index. /// </returns> protected virtual int GetItemIndex(DataGrid owner, CellRef cell) { if (owner.WrapItems) { return(owner.ItemsInRows ? (cell.Row * owner.Columns) + cell.Column : (cell.Column * owner.Rows) + cell.Row); } return(owner.ItemsInRows ? cell.Row : cell.Column); }
/// <summary> /// The try extrapolate. /// </summary> /// <param name="cell"> /// The cell. /// </param> /// <param name="p1"> /// The p 1. /// </param> /// <param name="p2"> /// The p 2. /// </param> /// <param name="result"> /// The result. /// </param> /// <returns> /// The try extrapolate. /// </returns> private bool TryExtrapolate(CellRef cell, CellRef p1, CellRef p2, out object result) { try { var v1 = this.GetCellValue(p1); var v2 = this.GetCellValue(p2); try { double d1 = Convert.ToDouble(v1); double d2 = Convert.ToDouble(v2); v1 = d1; v2 = d2; } catch (Exception) { } int deltaColumns = p2.Column - p1.Column; int deltaRows = p2.Row - p1.Row; double f = 0; if (cell.Column < p1.Column || cell.Column > p2.Column) { if (deltaColumns > 0) { f = 1.0 * (cell.Column - p1.Column) / deltaColumns; } } if (cell.Row < p1.Row || cell.Row > p2.Row) { if (deltaRows > 0) { f = 1.0 * (cell.Row - p1.Row) / deltaRows; } } if (f == 0) { result = v1; return(true); } object tmp1, tmp2, tmp3; ReflectionMath.TrySubtract(v2, v1, out tmp1); ReflectionMath.TryMultiply(tmp1, f, out tmp2); ReflectionMath.TryAdd(v1, tmp2, out tmp3); result = tmp3; return(true); } catch { result = null; return(false); } }
/// <summary> /// Creates the cell definition for the specified cell. /// </summary> /// <param name="owner">The owner.</param> /// <param name="cell">The cell.</param> /// <returns> /// The cell definition /// </returns> public virtual CellDefinition CreateCellDefinition( DataGrid owner, CellRef cell) { var pd = owner.GetPropertyDefinition(cell); var item = owner.Operator.GetItem(owner, cell); var cd = this.CreateCellDefinitionOverride(owner, cell, pd, item); this.ApplyProperties(cd, owner, cell, pd, item); return cd; }
/// <summary> /// The try extrapolate. /// </summary> /// <param name="cell"> /// The cell. /// </param> /// <param name="currentCell"> /// The current cell. /// </param> /// <param name="selectionCell"> /// The selection cell. /// </param> /// <param name="autoFillRef"> /// The auto fill ref. /// </param> /// <param name="result"> /// The result. /// </param> /// <returns> /// The try extrapolate. /// </returns> public bool TryExtrapolate( CellRef cell, CellRef currentCell, CellRef selectionCell, CellRef autoFillRef, out object result) { int selMinRow = Math.Min(currentCell.Row, selectionCell.Row); int selMaxRow = Math.Max(currentCell.Row, selectionCell.Row); int selMinCol = Math.Min(currentCell.Column, selectionCell.Column); int selMaxCol = Math.Max(currentCell.Column, selectionCell.Column); int i = cell.Row; int j = cell.Column; // skip cells inside selection area if (i >= selMinRow && i <= selMaxRow && j >= selMinCol && j <= selMaxCol) { result = null; return(false); } object value = null; if (i < selMinRow) { this.TryExtrapolate(cell, new CellRef(selMinRow, j), new CellRef(selMaxRow, j), out value); } if (i > selMaxRow) { this.TryExtrapolate(cell, new CellRef(selMinRow, j), new CellRef(selMaxRow, j), out value); } if (j < selMinCol) { this.TryExtrapolate(cell, new CellRef(i, selMinCol), new CellRef(i, selMaxCol), out value); } if (j > selMaxCol) { this.TryExtrapolate(cell, new CellRef(i, selMinCol), new CellRef(i, selMaxCol), out value); } if (value == null) { var source = new CellRef(PeriodicClamp(i, selMinRow, selMaxRow), PeriodicClamp(j, selMinCol, selMaxCol)); value = this.GetCellValue(source); } if (value != null) { result = value; return(true); } result = null; return(false); }
/// <summary> /// Gets the type of the property in the specified cell. /// </summary> /// <param name="definition">The definition.</param> /// <param name="cell">The cell.</param> /// <param name="currentValue">The current value.</param> /// <returns> /// The type of the property. /// </returns> public virtual Type GetPropertyType(PropertyDefinition definition, CellRef cell, object currentValue) { var descriptor = this.GetPropertyDescriptor(definition); if (descriptor?.PropertyType == null) { return(currentValue?.GetType() ?? typeof(object)); } return(descriptor.PropertyType); }
public bool TryExtrapolate(CellRef cell, CellRef currentCell, CellRef selectionCell, CellRef autoFillRef, out object result) { int selMinRow = Math.Min(currentCell.Row, selectionCell.Row); int selMaxRow = Math.Max(currentCell.Row, selectionCell.Row); int selMinCol = Math.Min(currentCell.Column, selectionCell.Column); int selMaxCol = Math.Max(currentCell.Column, selectionCell.Column); int i = cell.Row; int j = cell.Column; // skip cells inside selection area if (i >= selMinRow && i <= selMaxRow && j >= selMinCol && j <= selMaxCol) { result = null; return false; } object value = null; if (i < selMinRow) { TryExtrapolate(cell, new CellRef(selMinRow, j), new CellRef(selMaxRow, j), out value); } if (i > selMaxRow) { TryExtrapolate(cell, new CellRef(selMinRow, j), new CellRef(selMaxRow, j), out value); } if (j < selMinCol) { TryExtrapolate(cell, new CellRef(i, selMinCol), new CellRef(i, selMaxCol), out value); } if (j > selMaxCol) { TryExtrapolate(cell, new CellRef(i, selMinCol), new CellRef(i, selMaxCol), out value); } if (value == null) { var source = new CellRef(PeriodicClamp(i, selMinRow, selMaxRow), PeriodicClamp(j, selMinCol, selMaxCol)); value = GetCellValue(source); } if (value != null) { result = value; return true; } result = null; return false; }
/// <summary> /// Gets the binding path for the specified cell. /// </summary> /// <param name="cell">The cell.</param> /// <returns> /// The binding path /// </returns> public override string GetBindingPath(CellRef cell) { var pd = this.GetPropertyDefinition(cell); if (pd?.PropertyName != null) { return(pd.PropertyName); } var index = this.GetItemIndex(cell); return($"[{index}]"); }
/// <summary> /// Sets value to item in cell. /// </summary> /// <param name="cell">The cell reference.</param> /// <param name="value">The value.</param> public override void SetValue(CellRef cell, object value) { var list = this.ItemsSource; if (list == null || cell.Column < 0 || cell.Row < 0) { return; } var index = this.Owner.GetItemIndex(cell); list[index] = value; }
/// <summary> /// Creates the cell definition object. /// </summary> /// <param name="owner">The owner.</param> /// <param name="cell">The cell.</param> /// <param name="pd">The property definition.</param> /// <param name="item">The item.</param> /// <returns>A cell definition.</returns> protected virtual CellDefinition CreateCellDefinitionOverride(DataGrid owner, CellRef cell, PropertyDefinition pd, object item) { var propertyType = owner.Operator.GetPropertyType(pd, cell, item); var tcd = pd as TemplateColumnDefinition; if (tcd != null) { return new TemplateCellDefinition { DisplayTemplate = tcd.CellTemplate, EditTemplate = tcd.CellEditingTemplate }; } if (propertyType.Is(typeof(bool))) { return new CheckCellDefinition(); } if (propertyType.Is(typeof(Color))) { return new ColorCellDefinition(); } if (propertyType.Is(typeof(Enum))) { var enumType = Nullable.GetUnderlyingType(propertyType) ?? propertyType; var values = Enum.GetValues(enumType).Cast<object>().ToList(); if (Nullable.GetUnderlyingType(propertyType) != null) { values.Insert(0, null); } return new SelectCellDefinition { ItemsSource = values }; } if (pd.ItemsSourceProperty != null || pd.ItemsSource != null) { return new SelectCellDefinition { ItemsSource = pd.ItemsSource, ItemsSourceProperty = pd.ItemsSourceProperty }; } return new TextCellDefinition(); }
/// <summary> /// Creates the cell descriptor for the specified cell. /// </summary> /// <param name="cell">The cell.</param> /// <returns>A cell descriptor.</returns> public CellDescriptor CreateCellDescriptor(CellRef cell) { var pd = this.GetPropertyDefinition(cell); var d = new CellDescriptor { PropertyDefinition = pd, Item = this.GetItem(cell), Descriptor = this.GetPropertyDescriptor(pd, null, cell), PropertyType = this.GetPropertyType(cell), BindingPath = this.GetBindingPath(cell), BindingSource = this.GetDataContext(cell) }; return(d); }
/// <summary> /// Gets the item in cell. /// </summary> /// <param name="owner">The owner.</param> /// <param name="cell">The cell reference.</param> /// <returns> /// The item <see cref="object" />. /// </returns> public override object GetItem(DataGrid owner, CellRef cell) { var list = owner.ItemsSource; if (list == null) { return null; } var index = this.GetItemIndex(owner, cell); if (index >= 0 && index < list.Count) { return list[index]; } return null; }
/// <summary> /// Tries to set cell value in the specified cell. /// </summary> /// <param name="cell">The cell.</param> /// <param name="value">The value.</param> /// <returns><c>true</c> if the cell value was set.</returns> public virtual bool TrySetCellValue(CellRef cell, object value) { if (this.Owner.ItemsSource == null) { return(false); } var item = this.GetItem(cell); var pd = this.GetPropertyDefinition(cell); if (pd == null) { return(false); } if (item == null || pd.IsReadOnly) { return(false); } var targetType = this.GetPropertyType(cell); if (!TryConvert(value, targetType, out var convertedValue)) { return(false); } try { var descriptor = this.GetPropertyDescriptor(pd, item, null); if (descriptor != null) { descriptor.SetValue(item, convertedValue); } else { this.SetValue(cell, convertedValue); } return(true); } catch (Exception) { return(false); } }
/// <summary> /// Gets the item in cell. /// </summary> /// <param name="cell">The cell reference.</param> /// <returns> /// The item <see cref="object" />. /// </returns> public override object GetItem(CellRef cell) { var list = this.ItemsSource; if (list == null) { return(null); } var index = Owner.GetItemIndex(cell); if (index >= 0 && index < list.Count) { return(list[index]); } return(null); }
/// <summary> /// Sets value to item in cell. /// </summary> /// <param name="cell">The cell reference.</param> /// <param name="value">The value.</param> public override void SetValue(CellRef cell, object value) { var list = this.ItemsSource; if (list == null || cell.Row < 0 || cell.Column < 0 || cell.Row >= list.Count) { return; } var row = list[cell.Row] as IList; if (row == null || cell.Column >= row.Count) { return; } row[cell.Column] = value; }
/// <summary> /// Gets the item in cell. /// </summary> /// <param name="owner">The owner.</param> /// <param name="cell">The cell reference.</param> /// <returns> /// The item <see cref="object" />. /// </returns> public override object GetItem(DataGrid owner, CellRef cell) { var list = owner.ItemsSource; if (list == null) { return(null); } var index = this.GetItemIndex(owner, cell); if (index >= 0 && index < list.Count) { return(list[index]); } return(null); }
/// <summary> /// Tries to set cell value in the specified cell. /// </summary> /// <param name="owner">The owner.</param> /// <param name="cell">The cell.</param> /// <param name="value">The value.</param> /// <returns><c>true</c> if the cell value was set.</returns> public virtual bool TrySetCellValue(DataGrid owner, CellRef cell, object value) { if (owner.ItemsSource != null) { var current = this.GetItem(owner, cell); var pd = owner.GetPropertyDefinition(cell); if (pd == null) { return(false); } if (current == null || pd.IsReadOnly) { return(false); } object convertedValue; var targetType = this.GetPropertyType(pd, cell, current); if (!TryConvert(value, targetType, out convertedValue)) { return(false); } var descriptor = this.GetPropertyDescriptor(pd); if (descriptor != null) { descriptor.SetValue(current, convertedValue); } else { this.SetValue(owner, cell, convertedValue); if (!(owner.ItemsSource is INotifyCollectionChanged)) { owner.UpdateCellContent(cell); } } return(true); } return(false); }
public void AutoFill(CellRef currentCell, CellRef selectionCell, CellRef autoFillRef) { for (int i = Math.Min(currentCell.Row, autoFillRef.Row); i <= Math.Max(currentCell.Row, autoFillRef.Row); i++) { for (int j = Math.Min(currentCell.Column, autoFillRef.Column); j <= Math.Max(currentCell.Column, autoFillRef.Column); j++) { object value; var cell = new CellRef(i, j); if (TryExtrapolate(cell, currentCell, selectionCell, autoFillRef, out value)) { TrySetCellValue(cell, value); // UpdateCellContent(cell); } } } }
/// <summary> /// Gets the item in cell. /// </summary> /// <param name="owner">The owner.</param> /// <param name="cell">The cell reference.</param> /// <returns> /// The <see cref="object" />. /// </returns> public override object GetItem(DataGrid owner, CellRef cell) { var list = owner.ItemsSource; var rowIndex = cell.Row; var columnIndex = cell.Column; if (list == null || rowIndex < 0 || columnIndex < 0) { return null; } if (rowIndex >= list.Count) { return null; } var row = list[rowIndex] as IList; if (row == null || columnIndex >= row.Count) { return null; } return ((IList)list[rowIndex])[columnIndex]; }
/// <summary> /// Applies the properties to the specified cell definition. /// </summary> /// <param name="cd">The cell definition.</param> /// <param name="owner">The owner.</param> /// <param name="cell">The cell.</param> /// <param name="pd">The row/column definition.</param> /// <param name="item">The current value of the cell.</param> protected virtual void ApplyProperties(CellDefinition cd, DataGrid owner, CellRef cell, PropertyDefinition pd, object item) { cd.HorizontalAlignment = pd.HorizontalAlignment; cd.BindingPath = pd.PropertyName ?? owner.Operator.GetBindingPath(owner, cell); cd.IsReadOnly = pd.IsReadOnly; cd.FormatString = pd.FormatString; if (pd.Converter != null) { cd.Converter = pd.Converter; } cd.ConverterParameter = pd.ConverterParameter; cd.ConverterCulture = pd.ConverterCulture; cd.IsEnabledBindingParameter = pd.IsEnabledByValue; cd.IsEnabledBindingPath = pd.IsEnabledByProperty; cd.BackgroundBindingPath = pd.BackgroundProperty; if (pd.Background != null) { cd.BackgroundBindingSource = pd.Background; cd.BackgroundBindingPath = string.Empty; } }
/// <summary> /// Gets the position of the specified cell. /// </summary> /// <param name="cellRef">The cell reference.</param> /// <returns> /// The upper-left position of the cell. /// </returns> public Point GetPosition(CellRef cellRef) { double x = 0; double y = 0; for (int j = 0; j < cellRef.Column && j < this.sheetGrid.ColumnDefinitions.Count; j++) { x += this.sheetGrid.ColumnDefinitions[j].ActualWidth; } for (int i = 0; i < cellRef.Row && i < this.sheetGrid.RowDefinitions.Count; i++) { y += this.sheetGrid.RowDefinitions[i].ActualHeight; } return new Point(x, y); }
/// <summary> /// Scroll the specified cell into view. /// </summary> /// <param name="cellRef">The cell reference.</param> public void ScrollIntoView(CellRef cellRef) { var pos0 = this.GetPosition(cellRef); var pos1 = this.GetPosition(new CellRef(cellRef.Row + 1, cellRef.Column + 1)); // todo: get correct size const double ScrollBarWidth = 20; const double ScrollBarHeight = 20; if (pos0.X < this.sheetScrollViewer.HorizontalOffset) { this.sheetScrollViewer.ScrollToHorizontalOffset(pos0.X); } if (pos1.X > this.sheetScrollViewer.HorizontalOffset + this.sheetScrollViewer.ActualWidth - ScrollBarWidth) { this.sheetScrollViewer.ScrollToHorizontalOffset( Math.Max(pos1.X - this.sheetScrollViewer.ActualWidth + ScrollBarWidth, 0)); } if (pos0.Y < this.sheetScrollViewer.VerticalOffset) { this.sheetScrollViewer.ScrollToVerticalOffset(pos0.Y); } if (pos1.Y > this.sheetScrollViewer.VerticalOffset + this.sheetScrollViewer.ActualHeight - ScrollBarHeight) { this.sheetScrollViewer.ScrollToVerticalOffset( Math.Max(pos1.Y - this.sheetScrollViewer.ActualHeight + ScrollBarHeight, 0)); } }
/// <summary> /// Inserts the display control for the specified cell. /// </summary> /// <param name="cellRef">The cell reference.</param> private void InsertDisplayControl(CellRef cellRef) { var e = this.CreateDisplayControl(cellRef, null, null); SetElementPosition(e, cellRef); this.sheetGrid.Children.Insert(this.cellInsertionIndex, e); this.cellInsertionIndex++; this.cellMap.Add(cellRef.GetHashCode(), e); }
/// <summary> /// Gets the item index for the specified cell. /// </summary> /// <param name="cell">The cell.</param> /// <returns> /// The get item index. /// </returns> protected virtual int GetItemIndex(CellRef cell) { var index = this.Owner.ItemsInRows ? cell.Row : cell.Column; return(this.GetItemsSourceIndex(index)); }
/// <summary> /// Gets the format string for the specified cell. /// </summary> /// <param name="cell">The cell reference.</param> /// <returns> /// The format string. /// </returns> private string GetFormatString(CellRef cell) { var pd = this.GetPropertyDefinition(cell); return pd != null ? pd.FormatString : null; }
/// <summary> /// Gets the item index for the specified cell. /// </summary> /// <param name="cell">The cell.</param> /// <returns> /// The get item index. /// </returns> private int GetItemIndex(CellRef cell) { if (this.WrapItems) { return this.ItemsInRows ? (cell.Row * this.Columns) + cell.Column : (cell.Column * this.Rows) + cell.Row; } return this.ItemsInRows ? cell.Row : cell.Column; }
/// <summary> /// Adds the display control for the specified cell. /// </summary> /// <param name="cellRef">The cell reference.</param> private void AddDisplayControl(CellRef cellRef) { var e = this.CreateDisplayControl(cellRef, null, null); if (e == null) { return; } SetElementPosition(e, cellRef); this.sheetGrid.Children.Add(e); this.cellMap.Add(cellRef.GetHashCode(), e); }
/// <summary> /// Handles changes in the current cell. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="DataTransferEventArgs" /> instance containing the event data.</param> /// <param name="changedCell">The cell that was changed.</param> private void CurrentCellSourceUpdated(object sender, DataTransferEventArgs e, CellRef changedCell) { // The source of the binding for the current cell was updated // (e.g. check box (display control) was changed or a combo box (edit control) was changed var value = this.GetCellValue(changedCell); var selectedCells = this.SelectedCells.ToArray(); if (!selectedCells.Contains(changedCell)) { // do not set other cells when changed cell is outside selection return; } // Set the same value in all selected cells. foreach (var cell in selectedCells) { if (changedCell.Equals(cell)) { // this value should already be set by the binding continue; } if (this.MultiChangeInChangedColumnOnly && cell.Column != changedCell.Column) { // do not change value in other columns when this property is set to true continue; } this.TrySetCellValue(cell, value); } }
/// <summary> /// Gets the binding path for the specified cell. /// </summary> /// <param name="cell">The cell.</param> /// <returns> /// The binding path /// </returns> public abstract string GetBindingPath(CellRef cell);
/// <summary> /// Gets the binding path for the specified cell. /// </summary> /// <param name="owner">The owner.</param> /// <param name="cell">The cell.</param> /// <returns> /// The binding path /// </returns> public override string GetBindingPath(DataGrid owner, CellRef cell) { return($"[{cell.Row}][{cell.Column}]"); }
/// <summary> /// Creates edit control. /// </summary> /// <param name="cell">The cell reference.</param> /// <param name="pd">The <see cref="PropertyDefinition" />.</param> /// <returns> /// The edit control. /// </returns> public override FrameworkElement CreateEditControl(CellRef cell, PropertyDefinition pd) { return(this.ControlFactory.CreateEditControl(pd, pd.GetBindingPath(cell))); }
/// <summary> /// Creates edit control. /// </summary> /// <param name="cell">The cell reference.</param> /// <param name="pd">The <see cref="PropertyDefinition" />.</param> /// <returns> /// The edit control. /// </returns> public override FrameworkElement CreateEditControl(CellRef cell, PropertyDefinition pd) { var index = Owner.GetItemIndex(cell); return(this.ControlFactory.CreateEditControl(pd, pd.GetBindingPath(index))); }
/// <summary> /// Gets the property definition for the specified cell. /// </summary> /// <param name="cell">The cell.</param> /// <returns>The property definition.</returns> public virtual PropertyDefinition GetPropertyDefinition(CellRef cell) { return(this.Owner.GetPropertyDefinition(cell)); }
/// <summary> /// The set element position. /// </summary> /// <param name="element">The element.</param> /// <param name="cell">The cell.</param> private static void SetElementPosition(UIElement element, CellRef cell) { Grid.SetColumn(element, cell.Column); Grid.SetRow(element, cell.Row); }
/// <summary> /// Sets value of the specified cell to the specified value. /// </summary> /// <param name="owner">The owner.</param> /// <param name="cell">The cell to change.</param> /// <param name="value">The value.</param> public abstract void SetValue(DataGrid owner, CellRef cell, object value);
/// <summary> /// Creates a edit control and bind it to the current cell element. /// </summary> /// <param name="cell">The cell reference.</param> /// <param name="pd">The <see cref="PropertyDefinition" />.</param> /// <returns> /// The <see cref="FrameworkElement" />. /// </returns> private FrameworkElement CreateEditControl(CellRef cell, PropertyDefinition pd) { return this.Operator.CreateEditControl(cell, pd); }
/// <summary> /// Gets the binding path for the specified cell. /// </summary> /// <param name="owner">The owner.</param> /// <param name="cell">The cell.</param> /// <returns> /// The binding path /// </returns> public abstract string GetBindingPath(DataGrid owner, CellRef cell);
/// <summary> /// Enumerate the items in the specified cell range. This is used to update the SelectedItems property. /// </summary> /// <param name="cell0">The cell 0.</param> /// <param name="cell1">The cell 1.</param> /// <returns> /// The items enumeration. /// </returns> private IEnumerable EnumerateItems(CellRef cell0, CellRef cell1) { var list = this.ItemsSource; if (list != null) { int index0 = this.ItemsInRows ? cell0.Row : cell0.Column; int index1 = this.ItemsInRows ? cell1.Row : cell1.Column; int min = Math.Min(index0, index1); int max = Math.Max(index0, index1); for (int index = min; index <= max; index++) { if (index >= 0 && index < list.Count) { yield return list[index]; } } } }
/// <summary> /// Converts the specified cell range to an array. /// </summary> /// <param name="cell1">The cell1.</param> /// <param name="cell2">The cell2.</param> /// <returns> /// An array. /// </returns> private object[,] ToArray(CellRef cell1, CellRef cell2) { int rowMin = Math.Min(cell1.Row, cell2.Row); int columnMin = Math.Min(cell1.Column, cell2.Column); int rowMax = Math.Max(cell1.Row, cell2.Row); int columnMax = Math.Max(cell1.Column, cell2.Column); int m = rowMax - rowMin + 1; int n = columnMax - columnMin + 1; var result = new object[m, n]; for (int i = rowMin; i <= rowMax; i++) { for (int j = columnMin; j <= columnMax; j++) { result[i - rowMin, j - columnMin] = this.GetCellValue(new CellRef(i, j)); } } return result; }
/// <summary> /// Gets the item for the specified cell. /// </summary> /// <param name="cell">The cell reference.</param> /// <returns> /// The item. /// </returns> private object GetItem(CellRef cell) { return this.Operator.GetItem(cell); }
/// <summary> /// Gets the cell reference for the specified position. /// </summary> /// <param name="position">The position.</param> /// <param name="isInAutoFillMode">if set to <c>true</c> [is in auto fill mode].</param> /// <param name="relativeTo">The relative to.</param> /// <returns> /// The cell reference. /// </returns> public CellRef GetCell(Point position, bool isInAutoFillMode = false, CellRef relativeTo = default(CellRef)) { double w = 0; int column = -1; int row = -1; for (int j = 0; j < this.sheetGrid.ColumnDefinitions.Count; j++) { double aw0 = j - 1 >= 0 ? this.sheetGrid.ColumnDefinitions[j - 1].ActualWidth : 0; double aw1 = this.sheetGrid.ColumnDefinitions[j].ActualWidth; double aw2 = j + 1 < this.sheetGrid.ColumnDefinitions.Count ? this.sheetGrid.ColumnDefinitions[j + 1].ActualWidth : 0; if (isInAutoFillMode) { if (relativeTo.Column <= j) { aw0 = 0; aw2 *= 0.5; } else { aw0 *= 0.5; aw2 = 0; } } else { aw0 = 0; aw2 = 0; } if (position.X > w - aw0 && position.X < w + aw1 + aw2) { column = j; break; } w += aw1; } if (w > 0 && column == -1) { column = this.sheetGrid.ColumnDefinitions.Count - 1; } double h = 0; for (int i = 0; i < this.sheetGrid.RowDefinitions.Count; i++) { double ah = this.sheetGrid.RowDefinitions[i].ActualHeight; if (position.Y < h + ah) { row = i; break; } h += ah; } if (h > 0 && row == -1) { row = this.sheetGrid.RowDefinitions.Count - 1; } if (column == -1 || row == -1) { return new CellRef(-1, -1); } return new CellRef(row, column); }
/// <summary> /// Gets the column/row definition for the specified cell. /// </summary> /// <param name="cell">The cell reference.</param> /// <returns> /// The column/row definition. /// </returns> private PropertyDefinition GetPropertyDefinition(CellRef cell) { int index = this.ItemsInRows ? cell.Column : cell.Row; if (index < this.PropertyDefinitions.Count) { return this.PropertyDefinitions[index]; } return null; }
/// <summary> /// Gets the formatted string value for the specified cell. /// </summary> /// <param name="cell">The cell.</param> /// <returns> /// The cell string. /// </returns> public string GetCellString(CellRef cell) { var value = this.GetCellValue(cell); if (value == null) { return null; } var formatString = this.GetFormatString(cell); return FormatValue(value, formatString); }
/// <summary> /// Sets value to items in cell. /// </summary> /// <param name="cell">The cell reference.</param> /// <param name="value">The value to be set.</param> private void SetValue(CellRef cell, object value) { if (this.ItemsSource == null) { return; } this.Operator.SetValue(cell, value); }
/// <summary> /// Updates the specified columns. /// </summary> /// <param name="columns">The column index.</param> private void UpdateColumns(int columns) { this.Columns = columns; for (int i = 0; i < columns; i++) { var w = this.GetColumnWidth(i); var cd1 = new System.Windows.Controls.ColumnDefinition { Width = w }; this.sheetGrid.ColumnDefinitions.Add(cd1); // bind the width of the header column to the width of the sheet column var cd2 = new System.Windows.Controls.ColumnDefinition(); this.columnGrid.ColumnDefinitions.Add(cd2); var binding = new Binding("Width") { Source = cd1, Mode = BindingMode.TwoWay }; cd2.SetBinding(System.Windows.Controls.ColumnDefinition.WidthProperty, binding); } // Add one empty column covering the vertical scrollbar this.columnGrid.ColumnDefinitions.Add( new System.Windows.Controls.ColumnDefinition { Width = new GridLength(40) }); // set the context menu this.columnGrid.ContextMenu = this.ColumnsContextMenu; this.columnGrid.Children.Add(this.columnSelectionBackground); for (int j = 0; j < columns; j++) { object header = this.GetColumnHeader(j); var cellref = new CellRef(this.ItemsInRows ? -1 : j, this.ItemsInRows ? j : -1); var pd = this.GetPropertyDefinition(cellref); var border = new Border { BorderBrush = this.HeaderBorderBrush, BorderThickness = new Thickness(0, 1, 1, 1), Margin = new Thickness(0, 0, j < columns - 1 ? -1 : 0, 0) }; Grid.SetColumn(border, j); this.columnGrid.Children.Add(border); var cell = header as FrameworkElement ?? new TextBlock { Text = header != null?header.ToString() : "-", VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = this.ItemsInRows ? pd.HorizontalAlignment : HorizontalAlignment.Center, Padding = new Thickness(4, 2, 4, 2) }; if (pd != null && pd.Tooltip != null) { ToolTipService.SetToolTip(cell, pd.Tooltip); } if (this.ColumnHeadersSource != null && this.ItemsInRows) { cell.DataContext = this.ColumnHeadersSource; cell.SetBinding(TextBlock.TextProperty, new Binding(string.Format("[{0}]", j)) { StringFormat = this.ColumnHeadersFormatString }); } Grid.SetColumn(cell, j); this.columnGrid.Children.Add(cell); this.columnHeaderMap[j] = cell; } for (int j = 0; j < columns; j++) { if (this.CanResizeColumns) { var splitter = new GridSplitter { ResizeDirection = GridResizeDirection.Columns, Background = Brushes.Transparent, Width = 5, RenderTransform = new TranslateTransform(3, 0), Focusable = false, VerticalAlignment = VerticalAlignment.Stretch, HorizontalAlignment = HorizontalAlignment.Right }; splitter.MouseDoubleClick += this.ColumnSplitterDoubleClick; splitter.DragStarted += this.ColumnSplitterChangeStarted; splitter.DragDelta += this.ColumnSplitterChangeDelta; splitter.DragCompleted += this.ColumnSplitterChangeCompleted; Grid.SetColumn(splitter, j); this.columnGrid.Children.Add(splitter); } } }
/// <summary> /// Exports the specified cell range to a string. /// </summary> /// <param name="cell1">The cell 1.</param> /// <param name="cell2">The cell 2.</param> /// <param name="separator">The separator.</param> /// <param name="encode">Determines whether to encode the elements.</param> /// <returns> /// The to string. /// </returns> private string ToString(CellRef cell1, CellRef cell2, string separator, bool encode = false) { int rowMin = Math.Min(cell1.Row, cell2.Row); int columnMin = Math.Min(cell1.Column, cell2.Column); int rowMax = Math.Max(cell1.Row, cell2.Row); int columnMax = Math.Max(cell1.Column, cell2.Column); var sb = new StringBuilder(); for (int i = rowMin; i <= rowMax; i++) { if (i > rowMin) { sb.AppendLine(); } for (int j = columnMin; j <= columnMax; j++) { string cell = this.GetCellString(new CellRef(i, j)); if (encode) { cell = CsvEncodeString(cell); } if (j > columnMin) { sb.Append(separator); } if (cell != null) { sb.Append(cell); } } } return sb.ToString(); }
/// <summary> /// Sets value of the specified cell to the specified value. /// </summary> /// <param name="cell">The cell to change.</param> /// <param name="value">The value.</param> public abstract void SetValue(CellRef cell, object value);
/// <summary> /// Gets the element at the specified cell. /// </summary> /// <param name="cellRef">The cell reference.</param> /// <returns> /// The element, or <c>null</c> if the cell was not found. /// </returns> public UIElement GetCellElement(CellRef cellRef) { UIElement e; return this.cellMap.TryGetValue(cellRef.GetHashCode(), out e) ? e : null; }
/// <summary> /// Creates the edit control for the specified cell. /// </summary> /// <param name="cell">The cell reference.</param> /// <param name="pd">The <see cref="PropertyDefinition" />.</param> /// <returns> /// The edit control. /// </returns> public abstract FrameworkElement CreateEditControl(CellRef cell, PropertyDefinition pd);
/// <summary> /// Gets the cell value from the Content property for the specified cell. /// </summary> /// <param name="cell">The cell reference.</param> /// <returns> /// The get cell value. /// </returns> public object GetCellValue(CellRef cell) { if (cell.Column < 0 || cell.Column >= this.Columns || cell.Row < 0 || cell.Row >= this.Rows) { return null; } var item = this.GetItem(cell); if (item != null) { var pd = this.GetPropertyDefinition(cell); if (pd != null) { if (pd.Descriptor != null) { return pd.Descriptor.GetValue(item); } return item; } } return null; }
/// <summary> /// Gets the item in the specified cell. /// </summary> /// <param name="cell">The cell reference.</param> /// <returns> /// The <see cref="object" />. /// </returns> public abstract object GetItem(CellRef cell);
/// <summary> /// Gets the visible cells. /// </summary> /// <param name="topLeftCell">The top left cell.</param> /// <param name="bottomRightCell">The bottom right cell.</param> public void GetVisibleCells(out CellRef topLeftCell, out CellRef bottomRightCell) { double left = this.sheetScrollViewer.HorizontalOffset; double right = left + this.sheetScrollViewer.ActualWidth; double top = this.sheetScrollViewer.VerticalOffset; double bottom = top + this.sheetScrollViewer.ActualHeight; topLeftCell = this.GetCell(new Point(left, top)); bottomRightCell = this.GetCell(new Point(right, bottom)); }
/// <summary> /// Creates the display control for the specified cell. /// </summary> /// <param name="cell">The cell.</param> /// <param name="pd">The property definition.</param> /// <param name="item">The item.</param> /// <returns> /// The display control. /// </returns> protected virtual UIElement CreateDisplayControl(CellRef cell, PropertyDefinition pd, object item) { FrameworkElement element = null; if (item == null) { item = this.GetItem(cell); } if (pd == null) { pd = this.GetPropertyDefinition(cell); } if (pd != null && item != null) { element = this.CreateDisplayControl(cell, pd); this.SetElementDataContext(element, pd, item); element.SourceUpdated += (s, e) => this.CurrentCellSourceUpdated(s, e, cell); element.VerticalAlignment = VerticalAlignment.Center; element.HorizontalAlignment = pd.HorizontalAlignment; } return element; }
/// <summary> /// Gets the item in the specified cell. /// </summary> /// <param name="owner">The owner.</param> /// <param name="cell">The cell reference.</param> /// <returns> /// The <see cref="object" />. /// </returns>au public abstract object GetItem(DataGrid owner, CellRef cell);
/// <summary> /// Updates the content of the specified cell. /// </summary> /// <param name="cellRef">The cell reference.</param> protected void UpdateCellContent(CellRef cellRef) { var c = this.GetCellElement(cellRef); if (c != null) { this.sheetGrid.Children.Remove(c); this.cellInsertionIndex--; this.cellMap.Remove(cellRef.GetHashCode()); } this.InsertDisplayControl(cellRef); }