The integration of InputPanel is more elaborate in case of FlexGrid as you need to create an empty template and cell factory objects to display the row details.
The following image shows an InputPanel integrated with a FlexGrid.
XAML |
Copy Code
|
---|---|
<Grid> <c1:C1FlexGrid x:Name="FlexGrid" MinRowHeight="1"> <c1:C1FlexGrid.Columns> <c1:Column Width="20" IsReadOnly="True"/> </c1:C1FlexGrid.Columns> </c1:C1FlexGrid> </Grid> |
Public Class Customer Public Property ID() As String Get Return m_ID End Get Set(value As String) m_ID = Value End Set End Property Private m_ID As String Public Property Country() As String Get Return m_Country End Get Set(value As String) m_Country = Value End Set End Property Private m_Country As String Public Property Name() As String Get Return m_Name End Get Set(value As String) m_Name = Value End Set End Property Private m_Name As String Public Property Age() As Integer Get Return m_Age End Get Set(value As Integer) m_Age = Value End Set End Property Private m_Age As Integer Public Property Weight() As Double Get Return m_Weight End Get Set(value As Double) m_Weight = Value End Set End Property Private m_Weight As Double Public Property Occupation() As Occupation Get Return m_Occupation End Get Set(value As Occupation) m_Occupation = Value End Set End Property Private m_Occupation As Occupation Public Property Phone() As String Get Return m_Phone End Get Set(value As String) m_Phone = Value End Set End Property Private m_Phone As String Public Property Salary() As Integer Get Return m_Salary End Get Set(value As Integer) m_Salary = Value End Set End Property Private m_Salary As Integer Public Sub New(id As String, country As String, _ name As String, age As Integer, weight As Double, _ occupation As Occupation, _ phone As String, salary As Integer) Me.ID = id Me.Country = country Me.Name = name Me.Age = age Me.Weight = weight Me.Occupation = occupation Me.Phone = phone Me.Salary = salary End Sub End Class Public Enum Occupation Doctor Artist Educator Engineer Executive Other End Enum
public class Customer { public string ID { get; set; } public string Country { get; set; } public string Name { get; set; } public int Age { get; set; } public double Weight { get; set; } public Occupation Occupation { get; set; } public string Phone { get; set; } public int Salary { get; set; } public Customer(string id, string country, string name, int age, double weight, Occupation occupation, string phone, int salary) { this.ID = id; this.Country = country; this.Name = name; this.Age = age; this.Weight = weight; this.Occupation = occupation; this.Phone = phone; this.Salary = salary; } } public enum Occupation { Doctor, Artist, Educator, Engineer, Executive, Other }
Dim data As New List(Of Customer)() data.Add(New Customer("100001", "United States", "Jack Danson", 40, 102.03, _ Occupation.Executive, _ "1371234567", 400000000)) data.Add(New Customer("100002", "China", "Tony Tian", 32, 82.2, _ Occupation.Engineer, _ "1768423846", 500)) data.Add(New Customer("100003", "Iran", "Larry Frommer", 15, 40.432, _ Occupation.Artist, _ "8473637486", 600)) data.Add(New Customer("100004", "Germany", "Charlie Krause", 26, 69.32, _ Occupation.Doctor, _ "675245438", 700)) data.Add(New Customer("100005", "India", "Mark Ambers", 51, 75.45, _ Occupation.Other, _ "1673643842", 800))
List<Customer> data = new List<Customer>(); data.Add(new Customer("100001", "United States", "Jack Danson", 40, 102.03, Occupation.Executive, "1371234567", 400000000)); data.Add(new Customer("100002", "China", "Tony Tian", 32, 82.2, Occupation.Engineer, "1768423846", 500)); data.Add(new Customer("100003", "Iran", "Larry Frommer", 15, 40.432, Occupation.Artist, "8473637486", 600)); data.Add(new Customer("100004", "Germany", "Charlie Krause", 26, 69.32, Occupation.Doctor, "675245438", 700)); data.Add(new Customer("100005", "India", "Mark Ambers", 51, 75.45, Occupation.Other, "1673643842", 800));
To display row details in an InputPanel, you need to create an empty template corresponding to each record that you add in FlexGrid. The template can be created by adding a new row after every record and merging the cells to form a single cell, which can be used to display an input panel.
'Add a row after every row in the grid and set its height to 0.1 Private Sub AddNewRowToFlexGrid(flexGrid As C1FlexGrid) Dim i As Integer = flexGrid.Rows.Count - 1 While i >= 0 Dim rw As New Row() rw.AllowMerging = True flexGrid.Rows.Insert(i + 1, rw) rw.Height = 0.1 i = i - 1 End While End Sub
//Add a row after every row in the grid and set its height to 0.1 private void AddNewRowToFlexGrid(C1FlexGrid flexGrid) { for (int i = flexGrid.Rows.Count - 1; i >= 0; i = i - 1) { Row rw = new Row(); rw.AllowMerging = true; flexGrid.Rows.Insert(i + 1, rw); rw.Height = 0.1; } }
'Initialize a method to add new row
AddNewRowToFlexGrid(FlexGrid)
//Initialize a method to add new row
AddNewRowToFlexGrid(FlexGrid);
'Class that implements cell merging Public Class MyMergeManager Implements IMergeManager Public Function GetMergedRange(grid As C1FlexGrid, _ cellType__1 As CellType, range As CellRange) _ As CellRange If grid.Rows(range.Row).DataItem Is Nothing Then If cellType__1 = CellType.Cell AndAlso range.Column >= 0 _ AndAlso range.Column < grid.Columns.Count Then range.Column = 0 range.Column2 = grid.Columns.Count - 1 End If End If Return range End Function End Class
//Class that implements cell merging public class MyMergeManager : IMergeManager { public CellRange GetMergedRange(C1FlexGrid grid, CellType cellType, CellRange range) { if (grid.Rows[range.Row].DataItem == null) if (cellType == CellType.Cell && range.Column >= 0 && range.Column < grid.Columns.Count) { range.Column = 0; range.Column2 = grid.Columns.Count - 1; } return range; } }
'Initialize a merge manager to handle cell merging FlexGrid.MergeManager = New MyMergeManager()
//Initialize a merge manager to handle cell merging FlexGrid.MergeManager = new MyMergeManager();
'CellFactory class to customize grid cells Public Class MyCellFactory Inherits CellFactory Private _gr As Row Private _fg As C1FlexGrid Shared _bmpExpanded As ImageSource, _bmpCollapsed As ImageSource Public expandedList As New List(Of Integer)() Public Sub New() _bmpExpanded = ImageCell.GetImageSource("Expanded.png") _bmpCollapsed = ImageCell.GetImageSource("Collapsed.png") End Sub Public Overrides Sub _ CreateCellContent(grid As C1FlexGrid, bdr As Border, rng As CellRange) MyBase.CreateCellContent(grid, bdr, rng) If _fg Is Nothing Then _fg = grid End If If _fg.Rows(rng.Row).DataItem IsNot Nothing Then If rng.Column = 0 Then Dim customer As _ Customer = TryCast(grid.Rows(rng.Row).DataItem, Customer) If customer IsNot Nothing Then bdr.Child = Nothing Dim _nodeImage As Image _gr = grid.Rows(rng.Row) _nodeImage = New Image() If expandedList.Contains(rng.Row) Then _nodeImage.Source = _bmpExpanded Else _nodeImage.Source = _bmpCollapsed End If _nodeImage.Width = InlineAssignHelper(_nodeImage.Height, 9) _nodeImage.VerticalAlignment = VerticalAlignment.Center _nodeImage.Stretch = Stretch.None bdr.Child = _nodeImage AddHandler _nodeImage.PreviewMouseDown, AddressOf _nodeImage_PreviewMouseDown Else expandedList.Remove(rng.Row) _fg.Rows(rng.Row + 1).Height = 0.1 End If End If ElseIf rng.Column = 0 AndAlso rng.ColumnSpan > 1 Then Dim customer As Customer = TryCast(grid.Rows(rng.Row - 1).DataItem, Customer) Dim panel As New C1InputPanel() panel.CurrentItem = customer grid.Rows(rng.Row).Tag = _ grid.Rows(rng.Row - 1).ActualHeight * (grid.Columns.Count + 1) * 1.22 bdr.Child = panel bdr.Padding = New Thickness(1) grid.Rows(rng.Row).IsReadOnly = True End If End Sub 'Handler for Mouse Down event to toggle Expand/Collapse icon and change child row visibility Private Sub _nodeImage_PreviewMouseDown(sender As Object, e As MouseButtonEventArgs) Dim _row As Integer = _ Grid.GetRow(TryCast(VisualTreeHelper.GetParent(TryCast(e.OriginalSource, _ Image)), Border)) SetExpandCollapse(_row, sender) End Sub Public Sub SetExpandCollapse(_row As Integer, sender As Object) Dim image = TryCast(sender, Image) If expandedList.Contains(_row) Then _fg.Rows(_row + 1).Height = 0.1 expandedList.Remove(_row) image.Source = _bmpCollapsed Else If _fg.Rows(_row + 1).Tag IsNot Nothing Then _fg.Rows(_row + 1).Height = Double.Parse(_fg.Rows(_row + 1).Tag.ToString()) End If expandedList.Add(_row) image.Source = _bmpExpanded End If End Sub Private Shared Function InlineAssignHelper(Of T)(ByRef target As T, value As T) As T target = value Return value End Function End Class
//CellFactory class to customize grid cells public class MyCellFactory : CellFactory { Row _gr; C1FlexGrid _fg; static ImageSource _bmpExpanded, _bmpCollapsed; public List<int> expandedList = new List<int>(); public MyCellFactory() { _bmpExpanded = ImageCell.GetImageSource("Expanded.png"); _bmpCollapsed = ImageCell.GetImageSource("Collapsed.png"); } public override void CreateCellContent (C1FlexGrid grid, Border bdr, CellRange rng) { base.CreateCellContent(grid, bdr, rng); if (_fg == null) _fg = grid; if (_fg.Rows[rng.Row].DataItem != null) { if (rng.Column == 0) { Customer customer = (grid.Rows[rng.Row].DataItem as Customer); if (customer != null) { bdr.Child = null; Image _nodeImage; _gr = grid.Rows[rng.Row]; _nodeImage = new Image(); if (expandedList.Contains(rng.Row)) _nodeImage.Source = _bmpExpanded; else _nodeImage.Source = _bmpCollapsed; _nodeImage.Width = _nodeImage.Height = 9; _nodeImage.VerticalAlignment = VerticalAlignment.Center; _nodeImage.Stretch = Stretch.None; bdr.Child = _nodeImage; _nodeImage.PreviewMouseDown += _nodeImage_PreviewMouseDown; } else { expandedList.Remove(rng.Row); _fg.Rows[rng.Row + 1].Height = 0.1; } } } else if (rng.Column == 0 && rng.ColumnSpan > 1) { Customer customer = (grid.Rows[rng.Row - 1].DataItem as Customer); C1InputPanel panel = new C1InputPanel(); panel.CurrentItem = customer; grid.Rows[rng.Row].Tag = grid.Rows[rng.Row - 1].ActualHeight * (grid.Columns.Count + 1) * 1.22; bdr.Child = panel; bdr.Padding = new Thickness(1); grid.Rows[rng.Row].IsReadOnly = true; } } //Handler for Mouse Down event to toggle Expand/Collapse icon and change child row visibility void _nodeImage_PreviewMouseDown(object sender, MouseButtonEventArgs e) { int _row = Grid.GetRow (((VisualTreeHelper.GetParent(e.OriginalSource as Image) as Border))); SetExpandCollapse(_row, sender); } public void SetExpandCollapse(int _row, object sender) { var image = sender as Image; if (expandedList.Contains(_row)) { _fg.Rows[_row + 1].Height = 0.1; expandedList.Remove(_row); image.Source = _bmpCollapsed; } else { if (_fg.Rows[_row + 1].Tag != null) { _fg.Rows[_row + 1].Height = double.Parse(_fg.Rows[_row + 1].Tag.ToString()); } expandedList.Add(_row); image.Source = _bmpExpanded; } } }
'Create a cell factory object and assign it to FlexGrid _cellFactory = New MyCellFactory() FlexGrid.CellFactory = _cellFactory
//Create a cell factory object and assign it to FlexGrid _cellFactory = new MyCellFactory(); FlexGrid.CellFactory = _cellFactory;
'ImageCell class to apply image icons Public MustInherit Class ImageCell Inherits StackPanel Private imgSrc As ImageSource Public Sub New(row As Row) If imgSrc Is Nothing Then imgSrc = GetImageSource(GetImageResourceName()) End If Orientation = Orientation.Horizontal Dim img = New Image() img.Source = imgSrc img.Width = 25 img.Height = 15 img.VerticalAlignment = VerticalAlignment.Center img.Stretch = Stretch.None Children.Add(img) End Sub Public MustOverride Function GetImageResourceName() As String Public Shared Function GetImageSource(imageName As String) As ImageSource Dim imgConv = New ImageSourceConverter() Dim path As String = _ String.Format("pack://application:,,,/Integration-FlexGrid;component/Resources/{0}", _ imageName) Return DirectCast(imgConv.ConvertFromString(path), ImageSource) End Function End Class
//ImageCell class to apply image icons public abstract class ImageCell : StackPanel { ImageSource imgSrc; public ImageCell(Row row) { if (imgSrc == null) { imgSrc = GetImageSource(GetImageResourceName()); } Orientation = Orientation.Horizontal; var img = new Image(); img.Source = imgSrc; img.Width = 25; img.Height = 15; img.VerticalAlignment = VerticalAlignment.Center; img.Stretch = Stretch.None; Children.Add(img); } public abstract string GetImageResourceName(); public static ImageSource GetImageSource(string imageName) { var imgConv = new ImageSourceConverter(); string path = string.Format ("pack://application:,,,/Integration-FlexGrid;component/Resources/{0}", imageName); return (ImageSource)imgConv.ConvertFromString(path); } }
'Bind FlexGrid to Customer and allow cell merging
FlexGrid.ItemsSource = data
FlexGrid.AllowMerging = AllowMerging.Cells
//Bind FlexGrid to Customer and allow cell merging
FlexGrid.ItemsSource = data.ToList<Customer>();
FlexGrid.AllowMerging = AllowMerging.Cells;
'Subscribe events AddHandler FlexGrid.Loaded, AddressOf FlexGrid_Loaded AddHandler FlexGrid.SelectionChanging, AddressOf FlexGrid_SelectionChanging AddHandler FlexGrid.SortedColumn, AddressOf FlexGrid_SortedColumn
//Subscribe events
FlexGrid.Loaded += FlexGrid_Loaded;
FlexGrid.SelectionChanging += FlexGrid_SelectionChanging;
FlexGrid.SortedColumn += FlexGrid_SortedColumn;
'Handlers for Loaded, Selection Changing and Sorted Column events Private Sub FlexGrid_Loaded(sender As Object, e As RoutedEventArgs) FlexGrid.AutoSizeColumns(1, FlexGrid.Columns.Count - 1, 10) End Sub Private Sub FlexGrid_SelectionChanging(sender As Object, e As CellRangeEventArgs) Dim inputPanel As C1InputPanel = Nothing GetInputPanelElement(e.Panel, inputPanel) If inputPanel IsNot Nothing AndAlso e.CellRange.Row Mod 2 = 1 Then e.Cancel = True End If End Sub Private Sub FlexGrid_SortedColumn(sender As Object, e As CellRangeEventArgs) Dim flexGrid As C1FlexGrid = TryCast(sender, C1FlexGrid) AddNewRowToFlexGrid(flexGrid) End Sub
//Handlers for Loaded, Selection Changing and Sorted Column events private void FlexGrid_Loaded(object sender, RoutedEventArgs e) { FlexGrid.AutoSizeColumns(1, FlexGrid.Columns.Count - 1, 10); } private void FlexGrid_SelectionChanging(object sender, CellRangeEventArgs e) { C1InputPanel inputPanel = null; GetInputPanelElement(e.Panel, ref inputPanel); if (inputPanel != null && e.CellRange.Row % 2 == 1) { e.Cancel = true; } } private void FlexGrid_SortedColumn(object sender, CellRangeEventArgs e) { C1FlexGrid flexGrid = sender as C1FlexGrid; AddNewRowToFlexGrid(flexGrid); }