Blazor Tree Grid の行ドラッグ
Blazor Tree Grid の Ignite UI for Blazor 行ドラッグ機能は簡単に構成でき、マウスを使用して行を新しい位置にドラッグ アンド ドロップすることで、グリッド内の行を再配置するために使用されます。これはルートの IgbTreeGrid
コンポーネントで初期化され、RowDraggable
入力を介して構成できます。
Blazor Tree Grid 行ドラッグの例
using System;
using System.Collections.Generic;
public class EmployeesNestedDataItem
{
public double ID { get; set; }
public double Age { get; set; }
public double Salary { get; set; }
public double Productivity { get; set; }
public string City { get; set; }
public string Country { get; set; }
public string Phone { get; set; }
public string HireDate { get; set; }
public string Name { get; set; }
public string Title { get; set; }
public List<EmployeesNestedDataItem_EmployeesItem> Employees { get; set; }
}
public class EmployeesNestedDataItem_EmployeesItem
{
public double Age { get; set; }
public double Salary { get; set; }
public double Productivity { get; set; }
public string City { get; set; }
public string Country { get; set; }
public string Phone { get; set; }
public string HireDate { get; set; }
public double ID { get; set; }
public string Name { get; set; }
public string Title { get; set; }
}
public class EmployeesNestedData
: List<EmployeesNestedDataItem>
{
public EmployeesNestedData()
{
this.Add(new EmployeesNestedDataItem()
{
ID = 1,
Age = 55,
Salary = 80000,
Productivity = 90,
City = @"Berlin",
Country = @"Germany",
Phone = @"609-202-505",
HireDate = @"2008-03-20",
Name = @"John Winchester",
Title = @"Development Manager",
Employees = new List<EmployeesNestedDataItem_EmployeesItem>()
{
new EmployeesNestedDataItem_EmployeesItem()
{
Age = 43,
Salary = 70000,
Productivity = 80,
City = @"Hamburg",
Country = @"Germany",
Phone = @"609-444-555",
HireDate = @"2011-06-03",
ID = 3,
Name = @"Michael Burke",
Title = @"Senior Software Developer"
},
new EmployeesNestedDataItem_EmployeesItem()
{
Age = 29,
Salary = 60000,
Productivity = 80,
City = @"Munich",
Country = @"Germany",
Phone = @"609-333-444",
HireDate = @"2009-06-19",
ID = 2,
Name = @"Thomas Anderson",
Title = @"Senior Software Developer"
},
new EmployeesNestedDataItem_EmployeesItem()
{
Age = 31,
Salary = 90000,
Productivity = 80,
City = @"Warasw",
Country = @"Poland",
Phone = @"609-222-205",
HireDate = @"2014-08-18",
ID = 11,
Name = @"Monica Reyes",
Title = @"Software Development Team Lead"
},
new EmployeesNestedDataItem_EmployeesItem()
{
Age = 35,
Salary = 70000,
Productivity = 70,
City = @"Koln",
Country = @"Germany",
Phone = @"609-502-525",
HireDate = @"2015-09-17",
ID = 6,
Name = @"Roland Mendel",
Title = @"Senior Software Developer"
}}
});
this.Add(new EmployeesNestedDataItem()
{
ID = 4,
Age = 42,
Salary = 90000,
Productivity = 80,
City = @"Kielce",
Country = @"Poland",
Phone = @"609-202-505",
HireDate = @"2014-01-22",
Name = @"Ana Sanders",
Title = @"CEO",
Employees = new List<EmployeesNestedDataItem_EmployeesItem>()
{
new EmployeesNestedDataItem_EmployeesItem()
{
Age = 44,
Salary = 80000,
Productivity = 80,
City = @"Warasw",
Country = @"Poland",
Phone = @"609-202-505",
HireDate = @"2014-04-04",
ID = 14,
Name = @"Laurence Johnson",
Title = @"Director"
},
new EmployeesNestedDataItem_EmployeesItem()
{
Age = 25,
Salary = 85000,
Productivity = 55,
City = @"Paris",
Country = @"France",
Phone = @"609-202-505",
HireDate = @"2017-11-09",
ID = 5,
Name = @"Elizabeth Richards",
Title = @"Vice President"
},
new EmployeesNestedDataItem_EmployeesItem()
{
Age = 39,
Salary = 88000,
Productivity = 88,
City = @"London",
Country = @"UK",
Phone = @"609-202-505",
HireDate = @"2010-03-22",
ID = 13,
Name = @"Trevor Ashworth",
Title = @"Director"
}}
});
this.Add(new EmployeesNestedDataItem()
{
ID = 18,
Age = 49,
Salary = 77000,
Productivity = 70,
City = @"Manchester",
Country = @"UK",
Phone = @"222-555-577",
HireDate = @"2014-01-22",
Name = @"Victoria Lincoln",
Title = @"Senior Accountant",
Employees = new List<EmployeesNestedDataItem_EmployeesItem>()
{
new EmployeesNestedDataItem_EmployeesItem()
{
Age = 43,
Salary = 70000,
Productivity = 80,
City = @"Hamburg",
Country = @"Germany",
Phone = @"609-444-555",
HireDate = @"2011-06-03",
ID = 23,
Name = @"Thomas Burke",
Title = @"Senior Accountant"
},
new EmployeesNestedDataItem_EmployeesItem()
{
Age = 29,
Salary = 60000,
Productivity = 80,
City = @"Munich",
Country = @"Germany",
Phone = @"609-333-444",
HireDate = @"2009-06-19",
ID = 22,
Name = @"Michael Anderson",
Title = @"Junior Accountant"
},
new EmployeesNestedDataItem_EmployeesItem()
{
Age = 31,
Salary = 90000,
Productivity = 80,
City = @"Warasw",
Country = @"Poland",
Phone = @"609-222-205",
HireDate = @"2014-08-18",
ID = 21,
Name = @"Roland Reyes",
Title = @"Accountant Team Lead"
},
new EmployeesNestedDataItem_EmployeesItem()
{
Age = 35,
Salary = 70000,
Productivity = 70,
City = @"Koln",
Country = @"Germany",
Phone = @"609-502-525",
HireDate = @"2015-09-17",
ID = 24,
Name = @"Monica Mendel",
Title = @"Senior Software Developer"
}}
});
this.Add(new EmployeesNestedDataItem()
{
ID = 10,
Age = 61,
Salary = 85000,
Productivity = 890,
City = @"Lyon",
Country = @"France",
Phone = @"259-266-887",
HireDate = @"2010-01-01",
Name = @"Yang Wang",
Title = @"Localization Developer",
Employees = new List<EmployeesNestedDataItem_EmployeesItem>()
{
new EmployeesNestedDataItem_EmployeesItem()
{
Age = 31,
Salary = 90000,
Productivity = 80,
City = @"Warasw",
Country = @"Poland",
Phone = @"609-222-205",
HireDate = @"2014-08-18",
ID = 11,
Name = @"Monica Reyes",
Title = @"Software Development Team Lead"
},
new EmployeesNestedDataItem_EmployeesItem()
{
Age = 35,
Salary = 70000,
Productivity = 70,
City = @"Koln",
Country = @"Germany",
Phone = @"609-502-525",
HireDate = @"2015-09-17",
ID = 6,
Name = @"Roland Mendel",
Title = @"Senior Software Developer"
}}
});
this.Add(new EmployeesNestedDataItem()
{
ID = 35,
Age = 35,
Salary = 75000,
Productivity = 75,
City = @"Warasw",
Country = @"Poland",
Phone = @"688-244-844",
HireDate = @"2014-01-22",
Name = @"Janine Munoz",
Title = @"HR",
Employees = new List<EmployeesNestedDataItem_EmployeesItem>()
{
new EmployeesNestedDataItem_EmployeesItem()
{
Age = 43,
Salary = 70000,
Productivity = 80,
City = @"Hamburg",
Country = @"Germany",
Phone = @"609-444-555",
HireDate = @"2011-06-03",
ID = 3,
Name = @"Michael Burke",
Title = @"Senior Software Developer"
},
new EmployeesNestedDataItem_EmployeesItem()
{
Age = 31,
Salary = 90000,
Productivity = 80,
City = @"Warasw",
Country = @"Poland",
Phone = @"609-222-205",
HireDate = @"2014-08-18",
ID = 11,
Name = @"Monica Reyes",
Title = @"Software Development Team Lead"
}}
});
this.Add(new EmployeesNestedDataItem()
{
ID = 10,
Age = 49,
Salary = 95000,
Productivity = 80,
City = @"Krakow",
Country = @"Poland",
Phone = @"677-266-555",
HireDate = @"2010-01-01",
Name = @"Yang Wang",
Title = @"Sales Manager",
Employees = new List<EmployeesNestedDataItem_EmployeesItem>()
{
new EmployeesNestedDataItem_EmployeesItem()
{
Age = 29,
Salary = 60000,
Productivity = 80,
City = @"Munich",
Country = @"Germany",
Phone = @"609-333-444",
HireDate = @"2009-06-19",
ID = 2,
Name = @"Thomas Anderson",
Title = @"Senior Software Developer"
},
new EmployeesNestedDataItem_EmployeesItem()
{
Age = 35,
Salary = 70000,
Productivity = 70,
City = @"Koln",
Country = @"Germany",
Phone = @"609-502-525",
HireDate = @"2015-09-17",
ID = 6,
Name = @"Roland Mendel",
Title = @"Senior Software Developer"
}}
});
}
}
csusing System;
using System.Net.Http;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Text;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using IgniteUI.Blazor.Controls; // for registering Ignite UI modules
namespace Infragistics.Samples
{
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
// registering Ignite UI modules
builder.Services.AddIgniteUIBlazor(
typeof(IgbInputModule),
typeof(IgbPropertyEditorPanelModule),
typeof(IgbTreeGridModule),
typeof(IgbPaginatorModule)
);
await builder.Build().RunAsync();
}
}
}
cs
@using IgniteUI.Blazor.Controls
<div class="container vertical ig-typography">
<div class="container horizontal fill">
<div class="container vertical" style="padding: 0.5rem;">
<IgbTreeGrid
AutoGenerate="false"
Name="treeGrid"
@ref="treeGrid"
Id="treeGrid"
Data="EmployeesNestedData"
ChildDataKey="Employees"
RowDraggable=true
RowDragEndScript="OnTreeGridRowDragEndHandler"
Width="100%"
Height="100%"
>
<IgbColumn
Field="Name"
Header="Name"
DataType="GridColumnDataType.String"
Sortable="true"
Editable="true"
>
</IgbColumn>
<IgbColumn
Field="HireDate"
Header="Hire Date"
DataType="GridColumnDataType.Date"
Sortable="true"
>
</IgbColumn>
<IgbColumn
Field="Age"
Header="Age"
DataType="GridColumnDataType.Number"
Sortable="true"
>
</IgbColumn>
</IgbTreeGrid>
</div>
<div class="container vertical" style="padding: 0.5rem;">
<IgbTreeGrid AutoGenerate="false"
Name="treeGrid2"
@ref="treeGrid2"
Id="treeGrid2"
Data="Data2"
EmptyGridMessage="Drag and Drop a row from the left grid to this grid"
ChildDataKey="Employees"
Width="100%"
Height="100%"
>
<IgbColumn Field="Name"
Header="Name"
DataType="GridColumnDataType.String"
Sortable="true"
Editable="true"
>
</IgbColumn>
<IgbColumn Field="HireDate"
Header="Hire Date"
DataType="GridColumnDataType.Date"
Sortable="true"
>
</IgbColumn>
<IgbColumn Field="Age"
Header="Age"
DataType="GridColumnDataType.Number"
Sortable="true"
>
</IgbColumn>
</IgbTreeGrid>
</div>
</div>
</div>
@code {
protected override async Task OnAfterRenderAsync(bool firstRender)
{
var treeGrid = this.treeGrid;
var treeGrid2 = this.treeGrid2;
}
protected override void OnInitialized()
{
this.Data2 = new List<EmployeesNestedDataItem_EmployeesItem>() { };
}
private IgbTreeGrid treeGrid;
private IgbTreeGrid treeGrid2;
private List<EmployeesNestedDataItem_EmployeesItem> Data2 { get; set; }
private EmployeesNestedData _employeesNestedData = null;
public EmployeesNestedData EmployeesNestedData
{
get
{
if (_employeesNestedData == null)
{
_employeesNestedData = new EmployeesNestedData();
}
return _employeesNestedData;
}
}
}
razorfunction addRowAndChildrenTreeGrid(row, newData) {
if (newData.includes(row)) {
return;
}
else if (newData.length > 0 && row.Employees) {
for (let i = row.Employees.length; i >= 0; i--) {
if (newData.includes(row.Employees[i])) {
let index = newData.findIndex(element => element.ID === row.Employees[i].ID);
if (index > -1) {
newData.splice(index, 1);
}
}
}
}
for (let record of newData) {
if (record.Employees && record.Employees.includes(row)) {
return;
}
}
newData.push(row);
}
function OnTreeGridRowDragEndHandler(evt) {
const ghostElement = evt.detail.dragDirective.ghostElement;
const dragElementPos = ghostElement.getBoundingClientRect();
const gridPosition = treeGrid2.getBoundingClientRect();
const withinXBounds = dragElementPos.x >= gridPosition.x && dragElementPos.x <= gridPosition.x + gridPosition.width;
const withinYBounds = dragElementPos.y >= gridPosition.y && dragElementPos.y <= gridPosition.y + gridPosition.height;
if (withinXBounds && withinYBounds) {
const newData = [...treeGrid2.data];
const draggedRowData = evt.detail.dragData.data;
addRowAndChildrenTreeGrid(draggedRowData, newData);
treeGrid2.data = newData;
}
}
igRegisterScript("OnTreeGridRowDragEndHandler", OnTreeGridRowDragEndHandler, false);
js/*
CSS styles are loaded from the shared CSS file located at:
https://static.infragistics.com/xplatform/css/samples/
*/
css
このサンプルが気に入りましたか? 完全な Ignite UI for Blazorツールキットにアクセスして、すばやく独自のアプリの作成を開始します。無料でダウンロードできます。
構成
IgbTreeGrid
の行ドラッグを有効にするには、グリッドの RowDraggable
を true に設定します。これが有効になると、行ドラッグ ハンドルが各行に表示されます。このハンドルは行ドラッグを開始するために使用できます。ドラッグ ハンドルをクリックしてボタンを押しながらカーソルを動かすと、グリッドの RowDragStart
イベントが発生します。クリックをリリースすると、RowDragEnd
イベントが発生します。
<IgbTreeGrid RowDraggable="true">
</IgbTreeGrid>
razor
ドラッグ アイコンのテンプレート化
ドラッグ ハンドル アイコンは、グリッドの DragIndicatorIconTemplate
を使用してテンプレート化できます。作成している例で、アイコンをデフォルトのもの (drag_indicator) から drag_handle に変更します。
そのためには、DragIndicatorIcon
を使用して IgbTreeGrid
の本体内にテンプレートを渡すことができます。
<IgbTreeGrid Data="CustomersData" PrimaryKey="ID" RowDraggable="true" DragIndicatorIconTemplate="dragIndicatorIconTemplate" @ref="grid">
</IgbTreeGrid>
private RenderFragment<IgbGridEmptyTemplateContext> dragIndicatorIconTemplate = (context) =>
{
return @<div>
<IgbIcon IconName="drag_handle" Collection="material"></IgbIcon>
</div>;
};
razor
アプリケーション デモ
行の並べ替えデモ
グリッドの行ドラッグ イベントを使用して、ドラッグよる行の並べ替えるが可能なグリッドを作成できます。
<IgbTreeGrid Data="CustomersData" PrimaryKey="ID" RowDraggable="true" RowDragStartScript="WebTreeGridReorderRowStartHandler" RowDragEndScript="WebTreeGridReorderRowHandler"></IgbTreeGrid>
razor
グリッドに PrimaryKey が指定されていることを確認してください。ロジックが行を適切に並べ替えられるように、行には一意の識別子が必要です。
RowDraggable
が有効になり、ドロップ エリアが定義されたら、ドロップ イベントの単純なハンドラーを実装する必要があります。行をドラッグするときは、以下を確認してください:
- 行が展開されていますか? そうであれば、行を縮小します。
- 行はグリッド内にドロップされましたか?
- そうであれば、ドラッグされた行が他のどの行にドロップされましたか?
- ターゲット行が見つかれば、
Data
配列内のレコードの位置を入れ替えます。 - 行は最初に選択されてましたか? そうであれば、選択済みとしてマークします。
以下では、上記の実装を示します。
//in JavaScript
igRegisterScript("WebTreeGridReorderRowStartHandler", (args) => {
const draggedRow = args.detail.dragElement;
const row = this.treeGrid.getRowByIndex(draggedRow.getAttribute('data-rowindex'));
if (row.expanded) {
row.expanded = false;
}
}, false);
igRegisterScript("WebTreeGridReorderRowHandler", (args) => {
const ghostElement = args.detail.dragDirective.ghostElement;
const dragElementPos = ghostElement.getBoundingClientRect();
const grid = document.getElementsByTagName("igc-tree-grid")[0];
const rows = Array.prototype.slice.call(document.getElementsByTagName("igx-tree-grid-row"));
const currRowIndex = this.getCurrentRowIndex(rows,
{ x: dragElementPos.x, y: dragElementPos.y });
if (currRowIndex === -1) { return; }
// remove the row that was dragged and place it onto its new location
const draggedRow = args.detail.dragData.data;
const childRows = this.findChildRows(grid.data, draggedRow);
//remove the row that was dragged and place it onto its new location
grid.deleteRow(args.detail.dragData.key);
grid.data.splice(currRowIndex, 0, args.detail.dragData.data);
// reinsert the child rows
childRows.reverse().forEach(childRow => {
grid.data.splice(currRowIndex + 1, 0, childRow);
});
}, false);
function findChildRows(rows, parent) {
const childRows = [];
rows.forEach(row => {
if (row.ParentID === parent.ID) {
childRows.push(row);
// Recursively find children of current row
const grandchildren = this.findChildRows(rows, row);
childRows.push(...grandchildren);
}
});
return childRows;
}
function getCurrentRowIndex(rowList, cursorPosition) {
for (const row of rowList) {
const rowRect = row.getBoundingClientRect();
if (cursorPosition.y > rowRect.top + window.scrollY && cursorPosition.y < rowRect.bottom + window.scrollY &&
cursorPosition.x > rowRect.left + window.scrollX && cursorPosition.x < rowRect.right + window.scrollX) {
// return the index of the targeted row
return parseInt(row.attributes["data-rowindex"].value);
}
}
return -1;
}
razor
これらの簡単な手順で、ドラッグ/ドロップで行を並べ替えることができるグリッドを構成しました! 次のデモで、上記コードの動作を確認できます。
行の選択も有効で、ドラッグした行をドロップしても選択が保持されます。
using System;
using System.Collections.Generic;
public class EmployeesNestedTreeDataItem
{
public double Age { get; set; }
public string HireDate { get; set; }
public double ID { get; set; }
public string Name { get; set; }
public string Phone { get; set; }
public bool OnPTO { get; set; }
public double ParentID { get; set; }
public string Title { get; set; }
}
public class EmployeesNestedTreeData
: List<EmployeesNestedTreeDataItem>
{
public EmployeesNestedTreeData()
{
this.Add(new EmployeesNestedTreeDataItem()
{
Age = 55,
HireDate = @"2008-03-20",
ID = 1,
Name = @"Johnathan Winchester",
Phone = @"0251-031259",
OnPTO = false,
ParentID = -1,
Title = @"Development Manager"
});
this.Add(new EmployeesNestedTreeDataItem()
{
Age = 42,
HireDate = @"2014-01-22",
ID = 4,
Name = @"Ana Sanders",
Phone = @"(21) 555-0091",
OnPTO = true,
ParentID = -1,
Title = @"CEO"
});
this.Add(new EmployeesNestedTreeDataItem()
{
Age = 49,
HireDate = @"2014-01-22",
ID = 18,
Name = @"Victoria Lincoln",
Phone = @"(071) 23 67 22 20",
OnPTO = true,
ParentID = -1,
Title = @"Accounting Manager"
});
this.Add(new EmployeesNestedTreeDataItem()
{
Age = 61,
HireDate = @"2010-01-01",
ID = 10,
Name = @"Yang Wang",
Phone = @"(21) 555-0091",
OnPTO = false,
ParentID = -1,
Title = @"Localization Manager"
});
this.Add(new EmployeesNestedTreeDataItem()
{
Age = 43,
HireDate = @"2011-06-03",
ID = 3,
Name = @"Michael Burke",
Phone = @"0452-076545",
OnPTO = true,
ParentID = 1,
Title = @"Senior Software Developer"
});
this.Add(new EmployeesNestedTreeDataItem()
{
Age = 29,
HireDate = @"2009-06-19",
ID = 2,
Name = @"Thomas Anderson",
Phone = @"(14) 555-8122",
OnPTO = false,
ParentID = 1,
Title = @"Senior Software Developer"
});
this.Add(new EmployeesNestedTreeDataItem()
{
Age = 31,
HireDate = @"2014-08-18",
ID = 11,
Name = @"Monica Reyes",
Phone = @"7675-3425",
OnPTO = false,
ParentID = 1,
Title = @"Software Development Team Lead"
});
this.Add(new EmployeesNestedTreeDataItem()
{
Age = 35,
HireDate = @"2015-09-17",
ID = 6,
Name = @"Roland Mendel",
Phone = @"(505) 555-5939",
OnPTO = false,
ParentID = 11,
Title = @"Senior Software Developer"
});
this.Add(new EmployeesNestedTreeDataItem()
{
Age = 44,
HireDate = @"2009-10-11",
ID = 12,
Name = @"Sven Cooper",
Phone = @"0695-34 67 21",
OnPTO = true,
ParentID = 11,
Title = @"Senior Software Developer"
});
this.Add(new EmployeesNestedTreeDataItem()
{
Age = 44,
HireDate = @"2014-04-04",
ID = 14,
Name = @"Laurence Johnson",
Phone = @"981-443655",
OnPTO = false,
ParentID = 4,
Title = @"Director"
});
this.Add(new EmployeesNestedTreeDataItem()
{
Age = 25,
HireDate = @"2017-11-09",
ID = 5,
Name = @"Elizabeth Richards",
Phone = @"(2) 283-2951",
OnPTO = true,
ParentID = 4,
Title = @"Vice President"
});
this.Add(new EmployeesNestedTreeDataItem()
{
Age = 39,
HireDate = @"2010-03-22",
ID = 13,
Name = @"Trevor Ashworth",
Phone = @"981-443655",
OnPTO = true,
ParentID = 5,
Title = @"Director"
});
this.Add(new EmployeesNestedTreeDataItem()
{
Age = 44,
HireDate = @"2014-04-04",
ID = 17,
Name = @"Antonio Moreno",
Phone = @"(505) 555-5939",
OnPTO = false,
ParentID = 18,
Title = @"Senior Accountant"
});
this.Add(new EmployeesNestedTreeDataItem()
{
Age = 50,
HireDate = @"2007-11-18",
ID = 7,
Name = @"Pedro Rodriguez",
Phone = @"035-640230",
OnPTO = false,
ParentID = 10,
Title = @"Senior Localization Developer"
});
this.Add(new EmployeesNestedTreeDataItem()
{
Age = 27,
HireDate = @"2016-02-19",
ID = 8,
Name = @"Casey Harper",
Phone = @"0342-023176",
OnPTO = true,
ParentID = 10,
Title = @"Senior Localization"
});
this.Add(new EmployeesNestedTreeDataItem()
{
Age = 25,
HireDate = @"2017-11-09",
ID = 15,
Name = @"Patricia Simpson",
Phone = @"069-0245984",
OnPTO = false,
ParentID = 7,
Title = @"Localization Intern"
});
this.Add(new EmployeesNestedTreeDataItem()
{
Age = 39,
HireDate = @"2010-03-22",
ID = 9,
Name = @"Francisco Chang",
Phone = @"(91) 745 6200",
OnPTO = false,
ParentID = 7,
Title = @"Localization Intern"
});
this.Add(new EmployeesNestedTreeDataItem()
{
Age = 25,
HireDate = @"2018-03-18",
ID = 16,
Name = @"Peter Lewis",
Phone = @"069-0245984",
OnPTO = true,
ParentID = 7,
Title = @"Localization Intern"
});
}
}
csusing System;
using System.Net.Http;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Text;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using IgniteUI.Blazor.Controls; // for registering Ignite UI modules
namespace Infragistics.Samples
{
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
// registering Ignite UI modules
builder.Services.AddIgniteUIBlazor(
typeof(IgbInputModule),
typeof(IgbTreeGridModule)
);
await builder.Build().RunAsync();
}
}
}
cs
@using IgniteUI.Blazor.Controls
@inject IJSRuntime JS
<div class="container vertical ig-typography">
<div class="container vertical fill">
<IgbTreeGrid
AutoGenerate="false"
Name="treeGrid"
@ref="treeGrid"
Id="treeGrid"
Data="EmployeesNestedTreeData"
PrimaryKey="ID"
ForeignKey="ParentID"
RowDragStartScript="WebTreeGridReorderRowStartHandler"
RowDraggable="true"
RowDragEndScript="WebTreeGridReorderRowHandler">
<IgbColumn
Field="Name"
Header="Full Name"
DataType="GridColumnDataType.String"
Resizable="true"
Sortable="true"
Filterable="true"
Editable="true">
</IgbColumn>
<IgbColumn
Field="Age"
DataType="GridColumnDataType.Number"
Resizable="false"
Sortable="false"
Filterable="false"
Editable="true">
</IgbColumn>
<IgbColumn
Field="Title"
DataType="GridColumnDataType.String"
Resizable="true"
Sortable="true"
Filterable="true"
Editable="true">
</IgbColumn>
<IgbColumn
Field="HireDate"
Header="Hire Date"
DataType="GridColumnDataType.Date"
Resizable="true"
Sortable="true"
Filterable="true"
Editable="true">
</IgbColumn>
</IgbTreeGrid>
</div>
</div>
@code {
protected override async Task OnAfterRenderAsync(bool firstRender)
{
var treeGrid = this.treeGrid;
}
private IgbTreeGrid treeGrid;
private EmployeesNestedTreeData _employeesNestedTreeData = null;
public EmployeesNestedTreeData EmployeesNestedTreeData
{
get
{
if (_employeesNestedTreeData == null)
{
_employeesNestedTreeData = new EmployeesNestedTreeData();
}
return _employeesNestedTreeData;
}
}
}
razor
igRegisterScript("WebTreeGridReorderRowStartHandler", (args) => {
const draggedRow = args.detail.dragElement;
const row = this.treeGrid.getRowByIndex(draggedRow.getAttribute('data-rowindex'));
if (row.expanded) {
row.expanded = false;
}
}, false);
igRegisterScript("WebTreeGridReorderRowHandler", (args) => {
const ghostElement = args.detail.dragDirective.ghostElement;
const dragElementPos = ghostElement.getBoundingClientRect();
const grid = document.getElementsByTagName("igc-tree-grid")[0];
const rows = Array.prototype.slice.call(document.getElementsByTagName("igx-tree-grid-row"));
const currRowIndex = this.getCurrentRowIndex(rows,
{ x: dragElementPos.x, y: dragElementPos.y });
if (currRowIndex === -1) { return; }
const draggedRow = args.detail.dragData.data;
const childRows = this.findChildRows(grid.data, draggedRow);
//remove the row that was dragged and place it onto its new location
grid.deleteRow(args.detail.dragData.key);
grid.data.splice(currRowIndex, 0, args.detail.dragData.data);
// reinsert the child rows
childRows.reverse().forEach(childRow => {
grid.data.splice(currRowIndex + 1, 0, childRow);
});
}, false);
function findChildRows(rows, parent) {
const childRows = [];
rows.forEach(row => {
if (row.ParentID === parent.ID) {
childRows.push(row);
// Recursively find children of current row
const grandchildren = this.findChildRows(rows, row);
childRows.push(...grandchildren);
}
});
return childRows;
}
function getCurrentRowIndex(rowList, cursorPosition) {
for (const row of rowList) {
const rowRect = row.getBoundingClientRect();
if (cursorPosition.y > rowRect.top + window.scrollY && cursorPosition.y < rowRect.bottom + window.scrollY &&
cursorPosition.x > rowRect.left + window.scrollX && cursorPosition.x < rowRect.right + window.scrollX) {
// return the index of the targeted row
return parseInt(row.attributes["data-rowindex"].value);
}
}
return -1;
}
js/*
CSS styles are loaded from the shared CSS file located at:
https://static.infragistics.com/xplatform/css/samples/
*/
css
制限
現在、RowDraggable
に既知の制限はありません。
API リファレンス
RowDraggable
RowDragStart
RowDragEnd
IgbTreeGrid
その他のリソース
コミュニティに参加して新しいアイデアをご提案ください。