FlexGrid の場合は、空のテンプレートとセルファクトリオブジェクトを作成して行の詳細を表示する必要があるため、InputPanel の統合は少し複雑です。
次の図に、FlexGrid と統合された InputPanel を示します。
XAML |
コードのコピー
|
---|---|
<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 国() 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 名前() 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 年齢() 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 重量() 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 職業() 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 電話番号() 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 給料() 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 Me.名前 = name Me.年齢 = age Me.重量 = weight Me.職業 = occupation Me.電話番号 = phone Me.給料 = salary End Sub End Class Public Enum Occupation 医者, 芸術家, 教育者, エンジニア, 重役, その他 End Enum
public class Customer { public string ID { get; set; } public string 国 { get; set; } public string 名前 { get; set; } public string 電話番号 { get; set; } public int 給料 { get; set; } public int 年齢 { get; set; } public double 重量 { get; set; } public Occupation 職業 { 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; this.名前 = name; this.年齢 = age; this.重量 = weight; this.職業 = occupation; this.電話番号 = phone; this.給料 = salary; } } public enum Occupation { 医者, 芸術家, 教育者, エンジニア, 重役, その他 }
Dim data As New List(Of Customer)() data.Add(new Customer("100001", "米国", "Jack Danson", 40, 102.03, _ Occupation.重役, "1371234567", 400000000)); data.Add(new Customer("100002", "中国", "Tony Tian", 32, 82.2, _ Occupation.エンジニア, "1768423846", 500)); data.Add(new Customer("100003", "イラン", "Larry Frommer", 15, 40.432, _ Occupation.芸術家, "8473637486", 600)); data.Add(new Customer("100004", "ドイツ", "Charlie Krause", 26, 69.32, _ Occupation.医者, "675245438", 700)); data.Add(new Customer("100005", "インド", "Mark Ambers", 51, 75.45, _ Occupation.その他, "1673643842", 800));
List<Customer> data = new List<Customer>(); data.Add(new Customer("100001", "米国", "Jack Danson", 40, 102.03, _ Occupation.重役, "1371234567", 400000000)); data.Add(new Customer("100002", "中国", "Tony Tian", 32, 82.2, _ Occupation.エンジニア, "1768423846", 500)); data.Add(new Customer("100003", "イラン", "Larry Frommer", 15, 40.432, _ Occupation.芸術家, "8473637486", 600)); data.Add(new Customer("100004", "ドイツ", "Charlie Krause", 26, 69.32, _ Occupation.医者, "675245438", 700)); data.Add(new Customer("100005", "インド", "Mark Ambers", 51, 75.45, _ Occupation.その他, "1673643842", 800));
InputPanel に行の詳細を表示するには、FlexGrid に追加した各レコードに対応する空のテンプレートを作成する必要があります。テンプレートを作成するには、各レコードの後に新しい行を追加し、その中のセルを結合して単一のセルにします。このセルを使用して入力パネルを表示します。
'グリッド内の交互の行の後に行を追加し、その高さを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
//グリッド内の交互の行の後に行を追加し、その高さを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; } }
'新しい行を追加するためにメソッドを初期化します
AddNewRowToFlexGrid(FlexGrid)
//新しい行を追加するためにメソッドを初期化します
AddNewRowToFlexGrid(FlexGrid);
'セルマージを実装するクラス 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
//セルマージを実装するクラス 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; } }
'マージマネージャを初期化してセルマージを処理します FlexGrid.MergeManager = New MyMergeManager()
//マージマネージャを初期化してセルマージを処理します FlexGrid.MergeManager = new MyMergeManager();
'グリッドセルをカスタマイズするためのCellFactoryクラス 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 'Expand / Collapseアイコンを切り替えて子行の可視性を変更するためのMouse Downイベントのハンドラ 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クラス 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; } } //Expand / Collapseアイコンを切り替えて子行の可視性を変更するためのMouse Downイベントのハンドラ 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; } } }
'Cellfactoryオブジェクトを作成し、それをFlexGridに割り当てます _cellFactory = New MyCellFactory() FlexGrid.CellFactory = _cellFactory
//Cellfactoryオブジェクトを作成し、それをFlexGridに割り当てます _cellFactory = new MyCellFactory(); FlexGrid.CellFactory = _cellFactory;
'画像アイコンを適用するImageCellクラス 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クラス 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); } }
'FlexGridをCustomerにバインドし、セルのマージを許可します
FlexGrid.ItemsSource = data
FlexGrid.AllowMerging = AllowMerging.Cells
//FlexGridをCustomerにバインドし、セルのマージを許可します
FlexGrid.ItemsSource = data.ToList<顧客>();
FlexGrid.AllowMerging = AllowMerging.Cells;
'/イベントを登録します AddHandler FlexGrid.Loaded, AddressOf FlexGrid_Loaded AddHandler FlexGrid.SelectionChanging,AddressOf FlexGrid_SelectionChanging AddHandler FlexGrid.SortedColumn, AddressOf FlexGrid_SortedColumn
//イベントを登録します
FlexGrid.Loaded += FlexGrid_Loaded;
FlexGrid.SelectionChanging += FlexGrid_SelectionChanging;
FlexGrid.SortedColumn += FlexGrid_SortedColumn;
'Loadedのハンドラ、 Selection Changing およびSorted Column のイベント 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
//Loadedのハンドラ、 Selection Changing およびSorted Column のイベント 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); }