Please note that this control has been deprecated and replaced with the Grid component, and as such, we recommend migrating to that control. This will not be receiving any new features, bug fixes will be deprioritized. For help or questions on migrating your codebase to the Data Grid, please contact support.
Blazor 그리드 편집
Ignite UI for Blazor 일괄 업데이트로 셀 및 행 편집을 지원합니다. 참고로, 이는 현재 템플릿이 없는 열로 제한됩니다.
すぐに使用できる機能のフルセット は、ページング、ソート、フィルタリング、編集、グループ化から行と列の仮想化まで、あらゆる機能をカバーします。.NET 開発者には制限はありません。
Blazor Grid Editing Example
EXAMPLE
MODULES
DATA GENERATOR
DATA SOURCE
RAZOR
JS
CSS
using 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;
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) });
builder.Services.AddIgniteUIBlazor(
typeof (IgbDataGridModule),
typeof (IgbGridColumnOptionsModule)
);
await builder.Build().RunAsync();
}
}
}
cs コピー using System;
using System.Collections.Generic;
using System.Linq;
namespace Infragistics.Samples
{
public static class DataGenerator
{
readonly static string [] websites = { ".com" , ".gov" , ".edu" , ".org" };
readonly static string [] emails = { "gmail.com" , "yahoo.com" , "twitter.com" };
readonly static string [] genders = { "male" , "female" };
readonly static string [] maleNames = { "Kyle" , "Oscar" , "Ralph" , "Mike" , "Bill" , "Frank" , "Howard" , "Jack" , "Larry" , "Pete" , "Steve" , "Vince" , "Mark" , "Alex" , "Max" , "Brian" , "Chris" , "Andrew" , "Martin" , "Mike" , "Steve" , "Glenn" , "Bruce" };
readonly static string [] femaleNames = { "Gina" , "Irene" , "Katie" , "Brenda" , "Casey" , "Fiona" , "Holly" , "Kate" , "Liz" , "Pamela" , "Nelly" , "Marisa" , "Monica" , "Anna" , "Jessica" , "Sofia" , "Isabella" , "Margo" , "Jane" , "Audrey" , "Sally" , "Melanie" , "Greta" , "Aurora" , "Sally" };
readonly static string [] lastNames = { "Adams" , "Crowley" , "Ellis" , "Martinez" , "Irvine" , "Maxwell" , "Clark" , "Owens" , "Rooney" , "Lincoln" , "Thomas" , "Spacey" , "MOrgan" , "King" , "Newton" , "Fitzgerald" , "Holmes" , "Jefferson" , "Landry" , "Berry" , "Perez" , "Spencer" , "Starr" , "Carter" , "Edwards" , "Stark" , "Johnson" , "Fitz" , "Chief" , "Blanc" , "Perry" , "Stone" , "Williams" , "Lane" , "Jobs" , "Adams" , "Power" , "Tesla" };
readonly static string [] countries = { "USA" , "UK" , "France" , "Canada" , "Poland" };
readonly static string [] citiesUS = { "New York" , "Los Angeles" , "Miami" , "San Francisco" , "San Diego" , "Las Vegas" };
readonly static string [] citiesUK = { "London" , "Liverpool" , "Manchester" };
readonly static string [] citiesFR = { "Paris" , "Marseille" , "Lyon" };
readonly static string [] citiesCA = { "Toronto" , "Vancouver" , "Montreal" };
readonly static string [] citiesPL = { "Krakow" , "Warsaw" , "Wroclaw" , "Gdansk" };
readonly static string [] citiesJP = { "Tokyo" , "Osaka" , "Kyoto" , "Yokohama" };
readonly static string [] citiesGR = { "Berlin" , "Bonn" , "Cologne" , "Munich" , "Hamburg" };
readonly static string [] roadSuffixes = { "Road" , "Street" , "Way" };
readonly static string [] roadNames = { "Main" , "Garden" , "Broad" , "Oak" , "Cedar" , "Park" , "Pine" , "Elm" , "Market" , "Hill" };
public static Random Rand = new Random();
public static string GetWebsite ( )
{
return GetItem(websites);
}
public static string GetEmail ( )
{
return GetItem(emails);
}
public static double GetNumber (double min, double max )
{
return Math.Round(min + (Rand.NextDouble() * (max - min)));
}
public static int GetInteger (double min, double max )
{
return (int )GetNumber(min, max);
}
public static string GetPhone ( )
{
var phoneCode = GetNumber(100 , 900 );
var phoneNum1 = GetNumber(100 , 900 );
var phoneNum2 = GetNumber(1000 , 9000 );
var phone = phoneCode + "-" + phoneNum1 + "-" + phoneNum2;
return phone;
}
public static string GetGender ( )
{
return GetItem(genders);
}
public static string GetNameFirst (string gender )
{
if (gender == "male" )
return GetItem(maleNames);
else
return GetItem(femaleNames);
}
public static string GetNameLast ( )
{
return GetItem(lastNames);
}
public static string GetItem (string [] array )
{
var index = (int )Math.Round(GetNumber(0 , array.Length - 1 ));
return array[index];
}
public static string GetCountry ( )
{
return GetItem(countries);
}
public static string GetCity (string country )
{
if (country == "Canada" )
{
return GetItem(citiesCA);
}
else if (country == "France" )
{
return GetItem(citiesFR);
}
else if (country == "Poland" )
{
return GetItem(citiesPL);
}
else if (country == "USA" )
{
return GetItem(citiesUS);
}
else if (country == "Japan" )
{
return GetItem(citiesJP);
}
else if (country == "Germany" )
{
return GetItem(citiesGR);
}
else
{
return GetItem(citiesUK);
}
}
public static string GetStreet ( )
{
var num = Math.Round(GetNumber(100 , 300 )).ToString();
var road = GetItem(roadNames);
var suffix = GetItem(roadSuffixes);
return num + " " + road + " " + suffix;
}
public static DateTime GetBirthday ( )
{
var year = DateTime.Now.Year - GetInteger(30 , 50 );
var month = GetNumber(10 , 12 );
var day = GetNumber(20 , 27 );
return new DateTime(year, (int )month, (int )day);
}
public static DateTime GetDate ( )
{
var year = DateTime.Now.Year;
var month = GetNumber(10 , 12 );
var day = GetNumber(20 , 27 );
return new DateTime(year, (int )month, (int )day);
}
public static string Pad (int num, int size )
{
var s = num + "" ;
while (s.Length < size)
{
s = "0" + s;
}
return s;
}
public static string GetPhotoMale (int id )
{
return "https://static.infragistics.com/xplatform/images/people/GUY" + Pad(id, 2 ) + ".png" ;
}
public static string GetPhotoFemale (int id )
{
return "https://static.infragistics.com/xplatform/images/people/GIRL" + Pad(id, 2 ) + ".png" ;
}
private static int maleCount = 0 ;
private static int femaleCount = 0 ;
public static string GetPhoto (string gender )
{
if (gender == "male" )
{
maleCount++;
if (maleCount > 24 ) maleCount = 1 ;
return GetPhotoMale(maleCount);
}
else
{
femaleCount++;
if (femaleCount > 24 ) femaleCount = 1 ;
return GetPhotoFemale(femaleCount);
}
}
public static string GetGenderPhoto (string gender )
{
return "https://static.infragistics.com/xplatform/images/genders/" + gender + ".png" ;
}
public static string GetCountryFlag (string country )
{
return "https://static.infragistics.com/xplatform/images/flags/" + country + ".png" ;
}
public static string GetIncomeRange (double salary )
{
if (salary < 50000 )
{
return "Low" ;
}
else if (salary < 100000 )
{
return "Average" ;
}
else
{
return "High" ;
}
}
}
}
cs コピー using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace Infragistics.Samples
{
public class ObsEmployeeInfo : INotifyPropertyChanged
{
public string ID { get ; set ; }
public string Address { get ; set ; }
public double Age { get ; set ; }
public string Gender { get ; set ; }
public string FirstName { get ; set ; }
public string LastName { get ; set ; }
public string Name { get ; set ; }
public string Street { get ; set ; }
public string City { get ; set ; }
public string Email { get ; set ; }
public string Phone { get ; set ; }
public string Photo { get ; set ; }
public double Salary { get ; set ; }
public double Sales { get ; set ; }
public string Income { get ; set ; }
public int Index { get ; set ; }
public DateTime Birthday { get ; set ; }
public ObservableCollection<ObsEmployeeProductivity> Productivity { get ; set ; }
private string _Country;
public string Country
{
get { return _Country; }
set { if (_Country != value ) { OnCountryChanged(value ); } }
}
public string CountryFlag { get ; set ; }
protected void OnCountryChanged (string countryName )
{
_Country = countryName;
CountryFlag = DataGenerator.GetCountryFlag(countryName);
City = DataGenerator.GetCity(countryName);
OnPropertyChanged("Country" );
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged (string propertyName )
{
if (PropertyChanged != null )
{
PropertyChanged(this , new PropertyChangedEventArgs(propertyName));
}
}
}
public class ObsEmployeeProductivity
{
public double Value { get ; set ; }
public int Week { get ; set ; }
}
public static class ObsEmployeeData
{
public static ObservableCollection<ObsEmployeeInfo> Create (int ? count, bool ? useProductivity )
{
if (count == null ) count = 100 ;
var employees = new ObservableCollection<ObsEmployeeInfo>();
for (int i = 0 ; i < count; i++)
{
var age = Math.Round(DataGenerator.GetNumber(20 , 40 ));
var gender = DataGenerator.GetGender();
var firstName = DataGenerator.GetNameFirst(gender);
var lastName = DataGenerator.GetNameLast();
var street = DataGenerator.GetStreet();
var country = DataGenerator.GetCountry();
var city = DataGenerator.GetCity(country);
var email = firstName.ToLower() + "@" + DataGenerator.GetEmail();
var photoPath = DataGenerator.GetPhoto(gender);
var employee = new ObsEmployeeInfo
{
Index = i,
Address = street + ", " + city,
Age = age,
Birthday = DataGenerator.GetBirthday(),
City = city,
Email = email,
Gender = gender,
ID = DataGenerator.Pad(1001 + i, 4 ),
FirstName = firstName,
LastName = lastName,
Name = firstName + " " + lastName,
Photo = photoPath,
Phone = DataGenerator.GetPhone(),
Street = DataGenerator.GetStreet(),
Salary = DataGenerator.GetNumber(40 , 200 ) * 1000 ,
Sales = DataGenerator.GetNumber(200 , 980 ) * 1000 ,
};
employee.Country = country;
employee.Income = DataGenerator.GetIncomeRange(employee.Salary);
if (useProductivity.HasValue && useProductivity.Value)
{
employee.Productivity = GetProductivity(52 );
}
employees.Add(employee);
}
return employees;
}
public static ObservableCollection<ObsEmployeeProductivity> GetProductivity (int weekCount )
{
var productivity = new ObservableCollection<ObsEmployeeProductivity>();
for (var w = 1 ; w <= weekCount; w++)
{
var value = DataGenerator.GetNumber(-50 , 50 );
var prod = new ObsEmployeeProductivity
{
Value = value ,
Week = w
};
productivity.Add(prod);
};
return productivity;
}
}
}
cs コピー
@using System.Collections.ObjectModel
@using IgniteUI.Blazor.Controls
<div class ="container vertical" >
<div class ="options horizontal" >
<button @onclick ="OnCommitClick" disabled ="@ ButtonsDisabled " > Commit</button >
<button @onclick ="OnUndoClick" disabled ="@ ButtonsDisabled " > Undo</button >
<button @onclick ="OnRedoClick" disabled ="@ ButtonsDisabled " > Redo</button >
<label >
Edit Mode:
<select @bind ="GridEditMode" >
<option > @ EditModeType.None </option >
<option > @ EditModeType.Cell </option >
<option > @ EditModeType.CellBatch </option >
<option > @ EditModeType.Row </option >
</select >
</label >
<label >
Excel-style Editing
<select @bind ="GridEditModeClickAction" >
<option > @ EditModeClickAction.SingleClick </option >
<option > @ EditModeClickAction.DoubleClick </option >
</select >
</label >
</div >
<div class ="container vertical" >
@ if (Data != null )
{
<div style ="overflow: hidden" >
<IgbDataGrid Height ="100%" Width ="100%" @ref ="DataGridRef"
EditModeClickAction ="@ GridEditModeClickAction "
DefaultColumnMinWidth ="120"
AutoGenerateColumns ="false"
DataSource ="Data"
EditMode ="@ GridEditMode "
ActivationMode ="@ GridActivationMode.Cell "
SelectionMode ="@ DataGridSelectionMode.SingleRow "
SelectionBehavior ="@ GridSelectionBehavior.ModifierBased "
IsColumnOptionsEnabled ="true"
RowEditStarted ="OnRowEditStarted"
RowEditEnded ="OnRowEditEnded" >
<IgbTextColumn Field ="Name" Width ="@( "*>150" ) " />
<IgbTextColumn Field ="Street" HeaderText ="Street" Width ="@( "*>160" ) " />
<IgbTextColumn Field ="City" HeaderText ="City" Width ="@( "*>120" ) " />
<IgbNumericColumn Field ="Salary" HeaderText ="Salary" PositivePrefix ="$" ShowGroupingSeparator ="true" Width ="@( "*>120" ) " />
<IgbImageColumn IsEditable ="false" Field ="Photo" HeaderText ="Photo" ContentOpacity ="1" HorizontalAlignment ="@ CellContentHorizontalAlignment.Center " Width ="@( "*>110" ) " />
<IgbDateTimeColumn Field ="Birthday" HeaderText ="Date of Birth" Width ="@( "*>170" ) " />
<IgbTemplateColumn Field ="ButtonColumn" HeaderText ="Delete Row" CellUpdatingScript ="onUpdatingTemplateColumn" />
</IgbDataGrid >
</div >
}
</div >
</div >
@code {
public static IgbDataGrid DataGridRef;
private EditModeClickAction GridEditModeClickAction = EditModeClickAction.SingleClick;
private EditModeType _editMode;
public EditModeType GridEditMode
{
get { return _editMode; }
set
{
_editMode = value ;
if (_editMode == EditModeType.CellBatch)
{
ButtonsDisabled = false ;
}
else
{
ButtonsDisabled = true ;
}
}
}
private bool ButtonsDisabled { get ; set ; }
public static ObservableCollection <ObsEmployeeInfo > Data { get ; set ; }
protected override void OnInitialized ( )
{
Data = ObsEmployeeData.Create(100 , false );
this .GridEditMode = EditModeType.Cell;
}
private void OnCommitClick (MouseEventArgs e )
{
DataGridRef.CommitEdits();
StateHasChanged();
}
private void OnUndoClick (MouseEventArgs e )
{
DataGridRef.Undo();
StateHasChanged();
}
private void OnRedoClick (MouseEventArgs e )
{
DataGridRef.Redo();
StateHasChanged();
}
private void OnRowEditEnded (IgbGridRowEditEndedEventArgs e )
{
if (_editMode == EditModeType.CellBatch)
{
ButtonsDisabled = false ;
}
else
{
ButtonsDisabled = true ;
}
StateHasChanged();
}
private void OnRowEditStarted (IgbGridRowEditStartedEventArgs e )
{
if (_editMode == EditModeType.CellBatch)
{
ButtonsDisabled = true ;
}
else
{
ButtonsDisabled = false ;
}
StateHasChanged();
}
[JSInvokable ]
public static void ButtonClickActionAtBlazorLevel (object parameter )
{
int param = int .Parse(parameter.ToString());
var rowItem = DataGridRef.ActualDataSource.GetItemAtIndex(param);
DataGridRef.RemoveItem(rowItem);
}
}
razor コピー function onUpdatingTemplateColumn (grid, args ) {
let content = args.content;
var row = args.cellInfo.dataRow;
if (content.childElementCount === 0 ) {
var deleteButton = document .createElement("button" );
deleteButton.id = row;
var deleteSpan = document .createElement("span" );
deleteSpan.textContent = "DELETE" ;
deleteButton.appendChild(deleteSpan);
deleteButton.onclick = function ( ) {
var button = deleteButton;
DotNet.invokeMethodAsync('Infragistics.Samples' , 'ButtonClickActionAtBlazorLevel' , button.id);
}
content.appendChild(deleteButton);
}
}
igRegisterScript("onUpdatingTemplateColumn" , onUpdatingTemplateColumn, false );
js コピー
Like this sample? Get access to our complete Ignite UI for Blazor toolkit and start building your own apps in minutes. Download it for free.
개요
Blazor 데이터 그리드에서 편집은 Blazor 그리드의 EditMode
옵션을 사용하여 구성됩니다. 이 속성은 아래에 나열된 세 가지 다른 옵션을 사용합니다.
None
: 편집이 활성화되지 않습니다.
Cell
: 셀이 편집 모드로 들어가고 편집 모드를 종료할 때 값을 커밋할 수 있도록 허용합니다.
CellBatch
: 셀이 편집 모드로 들어갈 수 있도록 허용하지만 변경 사항은 커밋될 때까지 나중에 캐시됩니다.
Row
: 행이 편집 모드로 들어가고 종료 시 값을 커밋하도록 허용합니다.
CellBatch
로 설정된 경우 변경 사항을 커밋하려면 그리드에서 commitEdits
메서드를 수행해야 합니다. 그리드는 셀이 커밋될 때까지 셀을 기울임꼴로 표시하여 변경 사항을 데이터 소스에 다시 푸시할 시기를 제어합니다.
또한 onCellValueChanging
이벤트를 연결하고 새 값이 커밋되기 전에 검사하여 오류 처리를 수행할 수 있습니다. 그리드는 오류 메시지를 출력할 수 있는 setEditError
메소드를 노출합니다. 유효한 값이 입력될 때까지 셀이 편집 모드로 유지됩니다. 그렇지 않으면 유효하지 않은 값을 되돌리기 위해 그리드의 rejectEdit
메소드를 수행할 수 있습니다. 유효하지 않은 값이 발견되지 않으면 그리드의 acceptEdit
메소드를 호출하여 변경 사항을 커밋할 수도 있습니다.
commitID
이벤트 인수를 매개변수로 전달하는 acceptCommit
또는 rejectCommit
메소드를 통해 onDataCommitting
연결하여 그리드 수준에서 커밋을 승인하거나 거부할 수 있습니다. 이 이벤트는 또한 커밋되기 전에 모든 수정 사항을 저장하는 changes
컬렉션을 노출합니다. 예를 들어 changes
컬렉션에 노출된 TransactionType
속성을 통해 커밋이 추가, 업데이트 또는 삭제 작업에서 발생했는지 확인하고 필요한 경우 acceptCommit
또는 rejectCommit
수행할 수 있습니다.
Excel Style Editing
EditOnKeyPress
사용하면 Excel의 작동 방식과 유사하게 입력할 때 즉시 편집을 시작할 수 있습니다. 또한 EditModeClickAction
속성을 SingleClick
으로 설정하면 사용자가 다른 셀을 탐색하는 동안 셀을 빠르게 편집할 수 있습니다. 기본적으로 편집 모드로 들어가려면 두 번 클릭해야 합니다.
Code Snippet
다음은 데이터 그리드 편집 및 데이터 커밋을 구성하는 방법을 보여줍니다.
<IgbDataGrid Height ="100%" Width ="100%" @ref ="DataGridRef"
DataSource ="DataSource"
EditMode ="EditModeType.CellBatch" />
<button @onclick ="OnCommitClick" > Commit Data</button >
@code {
public IgbDataGrid DataGridRef;
private void OnCommitClick (MouseEventArgs e )
{
this .DataGridRef.CommitEdits();
}
}
razor
Undo/Redo batch changes
다음은 일괄 업데이트가 활성화된 동안 변경 사항을 되돌리는 방법을 보여줍니다.
<IgbDataGrid Height ="100%" Width ="100%" @ref ="DataGridRef"
DataSource ="DataSource"
EditMode ="EditModeType.CellBatch" />
<button @onclick ="OnUndoClick" > Undo</button >
<button @onclick ="OnRedoClick" > Redo</button >
@code {
public IgbDataGrid DataGridRef;
private void OnUndoClick (MouseEventArgs e )
{
this .DataGridRef.Undo();
}
private void OnRedoClick (MouseEventArgs e )
{
this .DataGridRef.Redo();
}
}
razor
Error Validation and Commit Integrity
다음은 편집 모드를 종료할 때 셀이 비어 있는지 확인하고 업데이트된 셀의 커밋만 수락하여 오류를 통합하는 방법을 보여줍니다.
<IgbDataGrid Height ="100%" Width ="100%"
@ref ="DataGridRef"
CellValueChanging ="OnCellValueChanging"
DataCommitting ="OnDataCommitting" >
</IgbDataGrid >
@code {
public IgbDataGrid DataGridRef;
public void OnCellValueChanging (IgbGridCellValueChangingEventArgs e )
{
if (e.NewValue == "" )
{
this .DataGridRef.SetEditError(e.EditID, "Error, cell is empty" );
this .DataGridRef.RejectEdit(e.EditID);
}
else
{
this .DataGridRef.AcceptEdit(e.EditID);
}
}
public void OnDataCommitting (IgbGridDataCommittingEventArgs e )
{
if (e.Changes[0 ].TransactionType == TransactionType.Update)
{
this .DataGridRef.AcceptCommit(e.CommitID);
}
else
{
this .DataGridRef.RejectCommit(e.CommitID);
}
}
}
razor
API References