/// <summary> /// Inserts item to <see cref="DataGrid" />. /// </summary> /// <param name="index">The index.</param> /// <returns> /// Returns <c>true</c> if insertion is successful, <c>false</c> otherwise. /// </returns> public override bool InsertItem(int index) { var list = this.ItemsSource; if (list == null) { return(false); } var itemType = TypeHelper.GetItemType(list); var newList = Owner.CreateInstance(itemType) as IList; var innerType = TypeHelper.GetInnerTypeOfList(list); if (innerType == null) { return(false); } if (this.Owner.ItemsInRows) { if (newList != null) { for (var ii = 0; ii < this.Owner.Columns; ii++) { newList.Add(Owner.CreateInstance(innerType)); } if (index < 0) { list.Add(newList); } else { list.Insert(index, newList); } } } else { // insert/append one new element to each list. foreach (var row in list.OfType <IList>()) { var newItem = Owner.CreateInstance(innerType); if (index < 0) { row.Add(newItem); } else { row.Insert(index, newItem); } } } return(true); }
/// <summary> /// Inserts item to <see cref="DataGrid" />. /// </summary> /// <param name="index">The index.</param> /// <returns> /// <c>true</c> if insertion is successful, <c>false</c> otherwise. /// </returns> public override bool InsertItem(int index) { var list = this.ItemsSource; if (list == null) { return(false); } var itemType = TypeHelper.GetItemType(list); object newItem = null; if (itemType == typeof(string)) { newItem = string.Empty; } if (itemType == typeof(double)) { newItem = 0.0; } if (itemType == typeof(int)) { newItem = 0; } try { if (newItem == null) { newItem = Owner.CreateInstance(itemType); } } catch { return(false); } if (index < 0) { list.Add(newItem); } else { list.Insert(index, newItem); } return(true); }
/// <summary> /// Updates the property definitions. /// </summary> /// <param name="owner">The owner.</param> public virtual void UpdatePropertyDefinitions(DataGrid owner) { this.descriptors.Clear(); // Set the property descriptors. var itemType = TypeHelper.GetItemType(owner.ItemsSource); var properties = TypeDescriptor.GetProperties(itemType); foreach (var pd in owner.PropertyDefinitions) { if (!string.IsNullOrEmpty(pd.PropertyName)) { var descriptor = properties[pd.PropertyName]; this.SetPropertiesFromDescriptor(pd, descriptor); this.descriptors[pd] = descriptor; } } }
/// <summary> /// Gets the item type. /// </summary> /// <returns> /// The type of the elements in the list. /// </returns> public override Type GetItemsType() { return(TypeHelper.GetItemType(this.ItemsSource)); }
public override void GenerateColumnDefinitions() { var list = this.ItemsSource; if (list == null) { return; } var view = CollectionViewSource.GetDefaultView(this.ItemsSource); var iitemProperties = view as IItemProperties; if (iitemProperties != null && iitemProperties.ItemProperties.Count > 0) { foreach (var info in iitemProperties.ItemProperties) { var descriptor = info.Descriptor as PropertyDescriptor; if (!descriptor.IsBrowsable) { continue; } Owner.ColumnDefinitions.Add( new ColumnDefinition { Descriptor = descriptor, Header = info.Name, HorizontalAlignment = Owner.DefaultHorizontalAlignment, Width = Owner.DefaultColumnWidth }); } return; } var itemType = TypeHelper.FindBiggestCommonType(list); var properties = TypeDescriptor.GetProperties(itemType); if (properties.Count == 0) { // Otherwise try to get the property descriptors from an instance properties = GetPropertiesFromInstance(list, itemType); } foreach (PropertyDescriptor descriptor in properties) { if (!descriptor.IsBrowsable) { continue; } Owner.ColumnDefinitions.Add( new ColumnDefinition { Descriptor = descriptor, Header = descriptor.Name, HorizontalAlignment = Owner.DefaultHorizontalAlignment, Width = Owner.DefaultColumnWidth }); } if (Owner.ColumnDefinitions.Count == 0) { var itemsType = TypeHelper.GetItemType(list); Owner.ColumnDefinitions.Add( new ColumnDefinition { PropertyType = itemsType, Header = itemsType.Name, HorizontalAlignment = Owner.DefaultHorizontalAlignment, Width = Owner.DefaultColumnWidth }); } }
/// <summary> /// Updates all the UIElements of the grid (both cells, headers, row and column lines). /// </summary> private void UpdateGridContent() { this.UnsubscribeNotifications(); if (this.sheetGrid == null) { // return if the template has not yet been applied return; } this.ClearContent(); if (this.ItemsSource == null) { return; } if (this.AutoGenerateColumns && this.PropertyDefinitions.Count == 0) { this.GenerateColumnDefinitions(); } // If PropertyType is undefined, use the type of the items in the ItemsSource Type itemsType = null; foreach (var pd in this.PropertyDefinitions) { if (pd.PropertyType == null) { if (itemsType == null) { itemsType = this.GetItemsType(); } pd.PropertyType = itemsType; } } // Determine if columns or rows are defined this.ItemsInColumns = this.PropertyDefinitions.FirstOrDefault(pd => pd is RowDefinition) != null; // If only PropertyName has been defined, use the type of the items to get the descriptor. Type itemType = null; foreach (var pd in this.PropertyDefinitions) { if (pd.Descriptor == null && !string.IsNullOrEmpty(pd.PropertyName)) { if (itemType == null) { itemType = TypeHelper.GetItemType(this.ItemsSource); } pd.Descriptor = TypeDescriptor.GetProperties(itemType)[pd.PropertyName]; } } int n = this.ItemsSource.Cast <object>().Count(); int m = this.PropertyDefinitions.Count; if (this.WrapItems) { n /= m; } int rows = this.ItemsInRows ? n : m; int columns = this.ItemsInRows ? m : n; var visibility = rows >= 0 ? Visibility.Visible : Visibility.Hidden; // Hide the row/column headers if the content is empty this.rowScrollViewer.Visibility = this.columnScrollViewer.Visibility = this.sheetScrollViewer.Visibility = this.topLeft.Visibility = visibility; if (rows < 0) { return; } this.UpdateRows(rows); this.UpdateColumns(columns); this.UpdateCells(rows, columns); this.UpdateSelectionVisibility(); this.ShowEditControl(); this.SubscribeToNotifications(); // Update column width when all the controls are loaded. Dispatcher.BeginInvoke(new Action(this.UpdateColumnWidths), DispatcherPriority.Loaded); }
/// <summary> /// Generate column definitions based on a list of items. /// </summary> /// <param name="list">The list of items.</param> /// <returns>A sequence of column definitions.</returns> /// <remarks>The constraint is that all the items in the ItemsSource's should be of the same type. /// For non built in type, a /// <code>public static T Parse(string s, IFormatProvider formatProvider)</code> and /// <code>public string ToString(string format, IFormatProvider formatProvider)</code> should be defined. /// interface type is not acceptable for no object instance can be created based on it.</remarks> protected override IEnumerable <ColumnDefinition> GenerateColumnDefinitions(IList list) { if (list == null) { yield break; } // Strategy 1: get properties from IItemProperties var view = CollectionViewSource.GetDefaultView(list); var itemPropertiesView = view as IItemProperties; if (itemPropertiesView?.ItemProperties != null && itemPropertiesView.ItemProperties.Count > 0) { foreach (var info in itemPropertiesView.ItemProperties) { var descriptor = info.Descriptor as PropertyDescriptor; if (descriptor == null || !descriptor.IsBrowsable) { continue; } var cd = new ColumnDefinition { PropertyName = descriptor.Name, Header = info.Name, HorizontalAlignment = this.DefaultHorizontalAlignment, Width = this.DefaultColumnWidth }; yield return(cd); } yield break; } // Strategy 2: get properties from type descriptor var itemType = TypeHelper.FindBiggestCommonType(list); var properties = TypeDescriptor.GetProperties(itemType); if (properties.Count == 0) { // Otherwise try to get the property descriptors from an instance properties = GetPropertiesFromInstance(list, itemType); } if (properties.Count > 0) { foreach (PropertyDescriptor descriptor in properties) { if (!descriptor.IsBrowsable) { continue; } var cd = new ColumnDefinition { PropertyName = descriptor.Name, Header = descriptor.Name, HorizontalAlignment = this.DefaultHorizontalAlignment, Width = this.DefaultColumnWidth }; yield return(cd); } yield break; } // Strategy 3: create a single column var itemsType = TypeHelper.GetItemType(list); yield return (new ColumnDefinition { Header = itemsType.Name, HorizontalAlignment = this.DefaultHorizontalAlignment, Width = this.DefaultColumnWidth }); }