/// <summary> /// Handles the select/de-select of a row. /// </summary> /// <param name="rowNumber">The row number.</param> /// <param name="selectionSource">Selection source.</param> /// <param name="e">Routed event arguments.</param> private void HandleSelect(int rowNumber, SelectionSource selectionSource, RoutedEventArgs e) { bool controlKeyDown; bool shiftKeyDown; if (this.mainView.View.Rows.Count < 1 || rowNumber >= this.mainView.View.Rows.Count || rowNumber < 0) { return; } DataBoundRow hitRow = this.mainView.View.Rows[rowNumber]; List<DataBoundRow> removedItems = new List<DataBoundRow>(); List<DataBoundRow> addedItems = new List<DataBoundRow>(); removedItems = new List<DataBoundRow>(); addedItems = new List<DataBoundRow>(); KeyboardHelper.GetMetaKeyState(out controlKeyDown, out shiftKeyDown); this.selectedIndex = rowNumber; if (shiftKeyDown == false) { this.AnchorRowIndex = rowNumber; } bool multiSelectAllowed = (this.SelectionMode == SelectionMode.MultipleExtended || this.SelectionMode == SelectionMode.MultipleSimple); // Multi-select? if ((controlKeyDown && multiSelectAllowed && selectionSource != SelectionSource.Keyboard) || (this.forceSelect && multiSelectAllowed)) { if (this.spacebarKeyDown) { return; } //// De-select via Control Key and mouse if (this.SelectedItems.Contains(hitRow) == true) { removedItems.Add(hitRow); this.SelectedItems.Remove(hitRow); this.SelectedItem = this.SelectedItems.Count > 0 ? this.SelectedItems[this.SelectedItems.Count - 1] : null; hitRow.Select(false); hitRow.Highlight(true); hitRow.RowFocus = true; hitRow.RowSelected = false; } else { //// Select via Control Key and mouse addedItems.Add(hitRow); this.SelectedItems.Add(hitRow); this.SelectedItem = hitRow; hitRow.RowFocus = true; hitRow.RowSelected = false; } if (this.lastRowHavingFocusIndex != -1 && hitRow.Index != this.lastRowHavingFocusIndex) { this.MainView.Rows[this.lastRowHavingFocusIndex].Highlight(false); } } else if (controlKeyDown && multiSelectAllowed && selectionSource == SelectionSource.Keyboard) { hitRow.Highlight(true); hitRow.RowFocus = true; this.handlingControlMultiSelection = true; if (this.spacebarKeyDown) { //// Select via Control Key and space-bar if (this.SelectedItems.IndexOf(hitRow) == -1) { this.SelectedItems.Add(hitRow); hitRow.Highlight(false); hitRow.Select(true); hitRow.RowSelected = true; hitRow.RowFocus = true; } else { //// De-select via Control Key and space-bar this.SelectedItems.Remove(hitRow); hitRow.Select(false); hitRow.Highlight(true); hitRow.RowSelected = false; hitRow.RowFocus = true; } } else if (this.SelectedItems.IndexOf(hitRow) != -1) { hitRow.Select(true); hitRow.RowFocus = true; } if (this.lastHitRow != null) { if (this.lastHitRow != hitRow) { this.lastHitRow.Highlight(false); this.lastHitRow.RowFocus = false; } if (this.SelectedItems.IndexOf(this.lastHitRow) != -1) { this.lastHitRow.Select(true); } } this.lastHitRow = hitRow; } else if ((shiftKeyDown && multiSelectAllowed)) { //// Handle shift based selected int startRow = this.anchorRowIndex <= rowNumber ? this.anchorRowIndex : rowNumber; int endRow = this.anchorRowIndex <= rowNumber ? rowNumber : this.anchorRowIndex; DataBoundRow unselectingRow; // Items before selection range... for (int beforeRowIndex = 0; beforeRowIndex < startRow; beforeRowIndex++) { unselectingRow = this.mainView.View.Rows[beforeRowIndex]; if (this.SelectedItems.Contains(unselectingRow) == true) { this.SelectedItems.Remove(unselectingRow); removedItems.Add(unselectingRow); unselectingRow.Select(false); unselectingRow.RowSelected = false; unselectingRow.RowFocus = false; } } // Items in selection range... for (int selectRowIndex = startRow; selectRowIndex <= endRow; selectRowIndex++) { DataBoundRow selectingRow = this.mainView.View.Rows[selectRowIndex]; if (this.SelectedItems.Contains(selectingRow) == false) { this.SelectedItems.Add(selectingRow); addedItems.Add(selectingRow); selectingRow.RowSelected = true; selectingRow.RowFocus = false; } this.SelectedItem = selectingRow; } // Items after selection range... for (int afterRowIndex = endRow + 1; afterRowIndex < this.mainView.View.Rows.Count - 1; afterRowIndex++) { unselectingRow = this.mainView.View.Rows[afterRowIndex]; if (this.SelectedItems.Contains(unselectingRow) == true) { this.SelectedItems.Remove(unselectingRow); removedItems.Add(unselectingRow); unselectingRow.Select(false); unselectingRow.RowSelected = false; unselectingRow.RowFocus = false; } } if (e.GetType() == typeof(System.Windows.Input.KeyEventArgs)) { if (endRow + 2 == this.mainView.View.Rows.Count && ((KeyEventArgs)e).Key == Key.Up) { unselectingRow = this.mainView.View.Rows[endRow + 1]; if (this.SelectedItems.Contains(unselectingRow) == true) { this.SelectedItems.Remove(unselectingRow); removedItems.Add(unselectingRow); unselectingRow.Select(false); unselectingRow.RowSelected = false; unselectingRow.RowFocus = false; } } } else if (e.GetType() == typeof(System.Windows.Input.MouseButtonEventArgs)) { if (endRow + 1 != this.mainView.View.Rows.Count) { unselectingRow = this.mainView.View.Rows[this.mainView.View.Rows.Count - 1]; if (this.SelectedItems.Contains(unselectingRow) == true) { this.SelectedItems.Remove(unselectingRow); removedItems.Add(unselectingRow); unselectingRow.Select(false); unselectingRow.RowSelected = false; unselectingRow.RowFocus = false; } } } } else { if (this.lastHitRow != null) { if (this.lastHitRow != hitRow) { this.lastHitRow.Highlight(false); this.lastHitRow.RowSelected = false; this.lastHitRow.RowFocus = false; } } this.ClearSelections(); removedItems.AddRange(this.selectedItems); this.SelectedItems.Clear(); removedItems.Remove(hitRow); addedItems.Add(hitRow); this.SelectedItems.Add(hitRow); this.SelectedItem = hitRow; hitRow.RowFocus = true; hitRow.RowSelected = true; } if (!this.handlingControlMultiSelection) { this.EnsureSelections(); } this.spacebarKeyDown = false; this.handlingControlMultiSelection = false; this.EnsureRowVisible(rowNumber); this.lastRowHavingFocusIndex = rowNumber; this.HandleSelectedRowCollection(); if (this.OnSelectionChanged != null) { #if SILVERLIGHT SelectionChangedEventArgs newSelectionChangedEventArgs = new SelectionChangedEventArgs(removedItems, addedItems); #else // TODO: Check whether this implementation is correct SelectionChangedEventArgs newSelectionChangedEventArgs = new SelectionChangedEventArgs(e.RoutedEvent, removedItems, addedItems); #endif this.OnSelectionChanged(this, newSelectionChangedEventArgs); } }
/// <summary> /// Initializes a new instance of the <see cref="DataBoundRow"/> class. /// </summary> /// <param name="previousRow">The previous DataBoundRow.</param> public DataBoundRow(DataBoundRow previousRow) { this.previousRow = previousRow; if (null != previousRow) { this.previousRow.NextRow = this; } }
/// <summary> /// Clears the contents of our columns and resets our state. /// </summary> public void Clear() { foreach (ColumnManager manager in this.columns) { manager.StackPanel.Children.Clear(); } this.rows = new Collection <DataBoundRow>(); this.hashGroupings.Clear(); this.groupingTitles.Clear(); this.lastRow = null; this.firstVisibleItemIndex = 0; this.lastVisibleItemIndex = -1; SummaryManager summaryMgr = this.columns[0].SummaryManager; if (summaryMgr != null && summaryMgr.MainPanel != null) { summaryMgr.MainPanel.Visibility = Visibility.Collapsed; } }
/// <summary> /// Called when the background property changes. /// </summary> /// <param name="rowInstance">The DataGridRow.</param> /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param> private static void OnBackgroundPropertyChanged(DependencyObject rowInstance, DependencyPropertyChangedEventArgs e) { DataBoundRow dataBoundRow = rowInstance as DataBoundRow; if (dataBoundRow != null && dataBoundRow.list != null && e.OldValue != e.NewValue) { bool processRow = false; foreach (Panel cellPanel in dataBoundRow.list) { if (true == processRow) { cellPanel.Background = e.NewValue as Brush; } else { processRow = true; } } } }
/// <summary> /// Sets the Row height. /// </summary> /// <param name="dataTemplate">Cell template.</param> private void SetRowHeight(FrameworkElement dataTemplate) { if (null == dataTemplate) { throw new System.ArgumentException(WrapDataGridResources.InvalidCellDataTemplate); } DataBoundRow row = row = this.hashCells[dataTemplate.Name] as DataBoundRow; if (null == row) { throw new System.ArgumentException(WrapDataGridResources.NoDataRowFound); } if (!row.RowCollapsed) { if (!Double.IsNaN(dataTemplate.ActualHeight) && !Double.IsInfinity(dataTemplate.ActualHeight)) { row.RowHeight = dataTemplate.ActualHeight; } } }
/// <summary> /// Adds an almost blank row(row with bare minimum data) to the list of rows. /// </summary> /// <param name="dataContext">The Data Context for the row.</param> public void AddBlank(object dataContext) { DataBoundRow tempRow = new DataBoundRow(this.lastRow); tempRow.HostingWrapDataGrid = this.HostingWrapDataGrid; tempRow.Visibility = Visibility.Visible; tempRow.DataContext = dataContext; bool addHeaderIntoPanel = false; DataBoundRowGrouping grouping = null; if (null != this.groupingTemplateLogic) { grouping = DataTemplateHelper.LoadContent(this.groupingTemplateLogic) as DataBoundRowGrouping; if (null != grouping) { grouping.DataSource = dataContext; tempRow.Grouping = grouping; if (null == this.lastRow) { // new header as we are the first row and we have a grouping template addHeaderIntoPanel = true; } else { if (this.lastRow.Grouping.GroupingText != tempRow.Grouping.GroupingText) { // we have a grouping template and we are not the same as the last row. addHeaderIntoPanel = true; } } // Update the groupings hash table. if (this.hashGroupings.ContainsKey(tempRow.Grouping.GroupingText)) { Collection <DataBoundRow> groupedRows = this.hashGroupings[tempRow.Grouping.GroupingText]; groupedRows.Add(tempRow); } else { Collection <DataBoundRow> groupedRows = new Collection <DataBoundRow>(); groupedRows.Add(tempRow); this.hashGroupings.Add(tempRow.Grouping.GroupingText, groupedRows); } } } // Indicates this row contains group header if (addHeaderIntoPanel && this.lastRow != null) { this.RaiseGroupingRenderEvent(); } foreach (ColumnManager column in this.columns) { if (this.rightToLeft) { column.StackPanel.Children.Insert(0, new StackPanel()); } else { column.StackPanel.Children.Add(new StackPanel()); } } tempRow.Index = this.rows.Count; tempRow.IsBlank = true; this.lastRow = tempRow; this.rows.Add(tempRow); }
/// <summary> /// Adds complete data to a blank row (row with partially filled data) created earlier. /// </summary> /// <param name="position">Position of the Blank Row.</param> public void FillBlankRowWithData(int position) { DataBoundRow row = this.rows[position]; object dataContext = row.DataContext; //// retrieve the data context stored earlier in the row. FrameworkElement groupingPresentation = null; bool addHeaderIntoPanel = false; // if this is not the first row, get the previous row's reference if (position > 0) { this.lastRow = this.rows[position - 1]; } if (null != this.groupingTemplateLogic) { if (null == this.lastRow) { // new header as we are the first row and we have a grouping template addHeaderIntoPanel = true; } else { if (this.lastRow.Grouping.GroupingText != row.Grouping.GroupingText) { // we have a grouping template and we are not the same as the last row. addHeaderIntoPanel = true; } } } // Indicates this row contains group header if (addHeaderIntoPanel && this.lastRow != null) { this.RaiseGroupingRenderEvent(); } this.lastRow = row; bool addGroupingTitle = true; bool bindHeights = false; if (this.columns.Count > 1) { bindHeights = true; } int replacePositionForRightToLeft = 0; foreach (ColumnManager column in this.columns) { cellId++; Panel dataTemplate = this.LoadContent(column) as Panel; dataTemplate.SetValue(FrameworkElement.NameProperty, String.Format(System.Globalization.CultureInfo.CurrentCulture, WrapDataGridResources.CellNameFormat, cellId)); if (null == dataTemplate) { throw new ArgumentException(WrapDataGridResources.InvalidCellTemplateRootElement); } StackPanel heightController = new StackPanel(); heightController.Orientation = Orientation.Vertical; ToolTip currentTooltip = new ToolTip(); dataTemplate.DataContext = dataContext; dataTemplate.Tag = string.Format(System.Globalization.CultureInfo.CurrentCulture, WrapDataGridResources.CellTagFormat, position, this.columns.Count - 1); if (column.ToolTipTemplate != null) { FrameworkElement tooltipElement = column.ToolTipTemplate.LoadContent() as FrameworkElement; tooltipElement.DataContext = dataContext; if (tooltipElement != null) { if (tooltipElement.GetType().ToString() == "System.Windows.Controls.ContentControl") { tooltipElement.Height = row.Height; tooltipElement.Width = column.Width; } currentTooltip.Content = tooltipElement; } if (currentTooltip != null) { ToolTipService.SetToolTip(heightController, currentTooltip); } } if (this.RightToLeft == true) { //// Actual replace position is calculated as below, since this is a Right to Left Type replacePositionForRightToLeft = this.rows.Count - 1 - position; if (replacePositionForRightToLeft < column.StackPanel.Children.Count) { column.StackPanel.Children.RemoveAt(replacePositionForRightToLeft); column.StackPanel.Children.Insert(replacePositionForRightToLeft, dataTemplate); } } else { if (true == addHeaderIntoPanel) { groupingPresentation = DataTemplateHelper.LoadContent(this.groupingTemplatePresentation) as FrameworkElement; if (null != groupingPresentation) { #if SILVERLIGHT if (null != groupingPresentation && null != WrapDataGridResources.GroupButtonName && null != groupingPresentation.FindName(WrapDataGridResources.GroupButtonName)) { Button hitButton = groupingPresentation.FindName(WrapDataGridResources.GroupButtonName) as Button; hitButton.IsTabStop = false; } TextBlock groupTitle = groupingPresentation.FindName(WrapDataGridResources.GroupTitleName) as TextBlock; #else // ADDED as FindName is not functioning in the WPF version TextBlock groupTitle = (groupingPresentation as Grid).Children[1] as TextBlock; #endif if (groupTitle == null) { throw new ArgumentNullException(WrapDataGridResources.NoGroupTitleElementFound); } // only add the title to the first column if (addGroupingTitle) { groupTitle.Text = row.Grouping.GroupingText; this.groupingTitles.Add(groupTitle); row.GroupingHeader = groupingPresentation; #if SILVERLIGHT if (null != WrapDataGridResources.GroupButtonName && null != groupingPresentation.FindName(WrapDataGridResources.GroupButtonName)) { Button hitButton = groupingPresentation.FindName(WrapDataGridResources.GroupButtonName) as Button; hitButton.IsTabStop = true; } #endif } groupingPresentation.MouseLeftButtonDown += new MouseButtonEventHandler(this.GroupingPresentation_MouseLeftButtonDown); groupingPresentation.SetValue(Grid.TagProperty, row.Grouping.GroupingText); groupingPresentation.SetValue(Grid.NameProperty, WrapDataGridResources.GroupingPresentationName); groupingPresentation.UpdateLayout(); #if !SILVERLIGHT if (addGroupingTitle) { groupingPresentation.UpdateLayout(); } #endif dataTemplate.Children.Add(groupingPresentation); dataTemplate.UpdateLayout(); addGroupingTitle = false; } } heightController.Children.Add(dataTemplate); // column.StackPanel.Children.Add(heightController); column.StackPanel.Children.RemoveAt(position); column.StackPanel.Children.Insert(position, heightController); } if (true == bindHeights) { System.Windows.Data.Binding binding = new System.Windows.Data.Binding(WrapDataGridResources.RowHeightPropertyName); binding.Source = row; heightController.SetBinding(StackPanel.HeightProperty, binding); dataTemplate.Loaded += new RoutedEventHandler(this.DataTemplate_Loaded); dataTemplate.SizeChanged += new SizeChangedEventHandler(this.DataTemplate_SizeChanged); row.List.Add(heightController); this.hashCells.Add(dataTemplate.Name, row); } } row.Index = position; row.IsBlank = false; }
/* * /// <summary> * /// ColumnManagers collection. * /// </summary> * /// <param name="dictionary">The resources ResourceDictionary.</param> * /// <returns>The collection of ColumnManagers.</returns> * public static Collection<ColumnManager> ColumnManagers(ResourceDictionary dictionary) * { * Collection<ColumnManager> collection = new Collection<ColumnManager>(); * foreach (object item in dictionary.Values) * { * ColumnManager manager = item as ColumnManager; * if (null != manager) * { * collection.Add(manager); * } * } * * return collection; * }*/ #endregion #region Public Methods /// <summary> /// Adds a row to the ColumnView. /// </summary> /// <param name="dataContext">The bound DataContext.</param> /// <returns>True if row was added successfully.</returns> public bool AddRow(object dataContext) { DataBoundRow row = new DataBoundRow(this.lastRow); row.HostingWrapDataGrid = this.HostingWrapDataGrid; row.Visibility = Visibility.Visible; row.DataContext = dataContext; bool addHeaderIntoPanel = false; DataBoundRowGrouping grouping = null; FrameworkElement groupingPresentation = null; if (null != this.groupingTemplateLogic) { grouping = DataTemplateHelper.LoadContent(this.groupingTemplateLogic) as DataBoundRowGrouping; if (null != grouping) { grouping.DataSource = dataContext; row.Grouping = grouping; if (null == this.lastRow) { // new header as we are the first row and we have a grouping template addHeaderIntoPanel = true; } else { if (this.lastRow.Grouping.GroupingText != row.Grouping.GroupingText) { // we have a grouping template and we are not the same as the last row. addHeaderIntoPanel = true; } } // Update the groupings hash table. if (this.hashGroupings.ContainsKey(row.Grouping.GroupingText)) { Collection <DataBoundRow> groupedRows = this.hashGroupings[row.Grouping.GroupingText]; groupedRows.Add(row); } else { Collection <DataBoundRow> groupedRows = new Collection <DataBoundRow>(); groupedRows.Add(row); this.hashGroupings.Add(row.Grouping.GroupingText, groupedRows); } } } // Indicates this row contains group header if (addHeaderIntoPanel && this.lastRow != null) { this.RaiseGroupingRenderEvent(); } this.lastRow = row; bool addGroupingTitle = true; bool bindHeights = false; if (this.columns.Count > 1) { bindHeights = true; } foreach (ColumnManager column in this.columns) { cellId++; Panel dataTemplate = this.LoadContent(column) as Panel; dataTemplate.SetValue(FrameworkElement.NameProperty, String.Format(System.Globalization.CultureInfo.CurrentCulture, WrapDataGridResources.CellNameFormat, cellId)); if (null == dataTemplate) { throw new ArgumentException(WrapDataGridResources.InvalidCellTemplateRootElement); } StackPanel heightController = new StackPanel(); heightController.Orientation = Orientation.Vertical; ToolTip currentTooltip = new ToolTip(); dataTemplate.DataContext = dataContext; if (column.ToolTipTemplate != null) { FrameworkElement tooltipElement = column.ToolTipTemplate.LoadContent() as FrameworkElement; tooltipElement.DataContext = dataContext; if (tooltipElement != null) { if (tooltipElement.GetType().ToString() == "System.Windows.Controls.ContentControl") { tooltipElement.Height = row.Height; tooltipElement.Width = column.Width; } currentTooltip.Content = tooltipElement; } if (currentTooltip != null) { ToolTipService.SetToolTip(heightController, currentTooltip); } } dataTemplate.Tag = string.Format(System.Globalization.CultureInfo.CurrentCulture, WrapDataGridResources.CellTagFormat, this.rows.Count, this.columns.Count - 1); if (this.RightToLeft == true) { column.StackPanel.Children.Insert(0, dataTemplate); } else { if (true == addHeaderIntoPanel) { groupingPresentation = DataTemplateHelper.LoadContent(this.groupingTemplatePresentation) as FrameworkElement; if (null != groupingPresentation) { #if SILVERLIGHT if (null != WrapDataGridResources.GroupButtonName && null != WrapDataGridResources.GroupButtonName && null != groupingPresentation.FindName(WrapDataGridResources.GroupButtonName)) { Button hitButton = groupingPresentation.FindName(WrapDataGridResources.GroupButtonName) as Button; hitButton.IsTabStop = false; } TextBlock groupTitle = groupingPresentation.FindName(WrapDataGridResources.GroupTitleName) as TextBlock; #else // ADDED as FindName is not functioning in the WPF version TextBlock groupTitle = (groupingPresentation as Grid).Children[1] as TextBlock; #endif if (groupTitle == null) { throw new ArgumentNullException(WrapDataGridResources.NoGroupTitleElementFound); } ////only add the title to the first column if (addGroupingTitle) { groupTitle.Text = row.Grouping.GroupingText; this.groupingTitles.Add(groupTitle); row.GroupingHeader = groupingPresentation; #if SILVERLIGHT if (null != WrapDataGridResources.GroupButtonName && null != groupingPresentation.FindName(WrapDataGridResources.GroupButtonName)) { Button hitButton = groupingPresentation.FindName(WrapDataGridResources.GroupButtonName) as Button; hitButton.IsTabStop = true; } #endif } groupingPresentation.MouseLeftButtonDown += new MouseButtonEventHandler(this.GroupingPresentation_MouseLeftButtonDown); groupingPresentation.SetValue(Grid.TagProperty, row.Grouping.GroupingText); groupingPresentation.SetValue(Grid.NameProperty, WrapDataGridResources.GroupingPresentationName); #if !SILVERLIGHT if (addGroupingTitle) { groupingPresentation.UpdateLayout(); } #endif dataTemplate.Children.Add(groupingPresentation); addGroupingTitle = false; } } heightController.Children.Add(dataTemplate); column.StackPanel.Children.Add(heightController); } if (true == bindHeights) { System.Windows.Data.Binding binding = new System.Windows.Data.Binding(WrapDataGridResources.RowHeightPropertyName); binding.Source = row; heightController.SetBinding(StackPanel.HeightProperty, binding); dataTemplate.Loaded += new RoutedEventHandler(this.DataTemplate_Loaded); dataTemplate.SizeChanged += new SizeChangedEventHandler(this.DataTemplate_SizeChanged); row.List.Add(heightController); this.hashCells.Add(dataTemplate.Name, row); } } row.Index = this.rows.Count; this.rows.Add(row); return(true); }
/// <summary> /// Initializes a new instance of the <see cref="DataBoundRow"/> class. /// </summary> /// <param name="previousRow">The previous DataBoundRow.</param> public DataBoundRow(DataBoundRow previousRow) { this.previousRow = previousRow; if (null != previousRow) { this.previousRow.NextRow = this; } }