Compare commits

...

76 Commits

Author SHA1 Message Date
Vladimir Enchev
d53d09e358 Version updated 2024-09-19 08:54:23 +03:00
Vladimir Enchev
34c02ac391 Upload will unable to upload empty file
Fix #1702
2024-09-19 08:51:26 +03:00
Atanas Korchev
cf4eb0c9cd Chart series annotations are sometimes duplicated. 2024-09-18 16:22:42 +03:00
Atanas Korchev
ee6220b1fe DataGrid row drag and drop works in day and month view. 2024-09-18 14:43:51 +03:00
Vladimir Enchev
a264638726 demo improved 2024-09-18 10:47:32 +03:00
Atanas Korchev
3e6a10a57d DataAnnotationValidator throws exception when used with double properties. Fixes #1689. 2024-09-18 09:55:55 +03:00
Vladimir Enchev
5258816770 SecurityCode input not focused after count change
Close #1700
2024-09-18 09:27:41 +03:00
Vladimir Enchev
fb4457f9a1 Dialog closes on ESC even if CloseDialogOnEsc = false in some cases
Fix #1699
2024-09-17 20:01:25 +03:00
Vladimir Enchev
627a74038c demos improved 2024-09-17 14:59:47 +03:00
Tcsaba66
54c297e898 create optional parameters for radzenhtmleritorimage (#1691) 2024-09-17 14:22:08 +03:00
Vladimir Enchev
a4d7201f7d DataFilter ToFilterString() should traverse filters exactly like Where() extension method 2024-09-17 09:51:15 +03:00
Atanas Korchev
b04cf69b90 Change the documentation link to point to the API reference. 2024-09-16 17:26:56 +03:00
Atanas Korchev
ea654f0b8d Remove the guides and redirect to the demos. 2024-09-16 17:14:03 +03:00
Vladimir Enchev
9b16aaf9e4 Version updated 2024-09-16 16:16:50 +03:00
yordanov
87672de761 Add utility css classes for display, overflow, sizing and borders 2024-09-16 16:13:02 +03:00
Vladimir Enchev
171a8def6d DataGrid KeyDown event added 2024-09-16 16:07:32 +03:00
Equitis
f09179f4cd Insert NumpadDecimal at cursor position. (#1693)
Co-authored-by: Patrick Fuhr <p.fuhr@solutit.de>
2024-09-16 16:01:54 +03:00
Vladimir Enchev
03f62068b3 DatePicker year DropDown should respect Culture 2024-09-16 14:59:51 +03:00
Atanas Korchev
828b4230e3 Required validation triggers unnecessarily for RadzenHtmlEditor. 2024-09-16 14:45:55 +03:00
Vladimir Enchev
2b23e5d472 demo fixed 2024-09-16 12:56:40 +03:00
Vladimir Enchev
17dbe70460 Pager will focus clicked button if not disabled 2024-09-13 16:38:45 +03:00
Atanas Korchev
587c3a0647 Remove outdated getting started instructions from the documentation. 2024-09-13 13:49:08 +03:00
Vladimir Enchev
83f0879b11 demo update to use Change instead onblur event 2024-09-13 10:53:38 +03:00
Vladimir Enchev
212b741828 demo updated 2024-09-13 10:26:23 +03:00
Vladimir Enchev
ee81b608f9 AutoComplete property deleted. All cases will be supported trough custom attribute 2024-09-12 16:06:23 +03:00
Vladimir Enchev
ad17080ee8 AutoComplete parameter type changed from bool to object to comply with .NET9
In .NET 9 it's not longer possible to have custom attribute and parameter with similar names - casing is ignored.
Details: https://github.com/dotnet/razor/issues/8854
2024-09-12 15:01:51 +03:00
Atanas Korchev
6a8611c348 Implement UploadComplete event in RadzenHtmlEditor. 2024-09-12 13:06:47 +03:00
Vladimir Enchev
3ba3610b21 DataGrid CheckBoxList column filter not refreshed on search when AllowCheckBoxListVirtualization="false" 2024-09-12 10:36:02 +03:00
Vladimir Enchev
8deed23e01 PropertyAccess.GetDynamicPropertyExpression() method added 2024-09-11 17:04:11 +03:00
Monsieurvor
356106263b NumericRangeValidator: AllowNull (#1686)
* AllowNull range validator

* Change comment

* Add AllowNull test case

* Fix test assertion

* Update RadzenNumericRangeValidator.cs
2024-09-11 15:25:10 +03:00
Vladimir Enchev
0566244b61 CSP tab added 2024-09-11 11:02:47 +03:00
Vladimir Enchev
17d76b4e6f Version updated 2024-09-11 09:57:55 +03:00
Vladimir Enchev
9c3490f275 Content-Security-Policy added to demos 2024-09-11 09:56:24 +03:00
Vladimir Enchev
b1b6499d7c DataGrid column AllowCheckBoxListVirtualization property added 2024-09-10 18:07:51 +03:00
Vladimir Enchev
a36a74091f Fixed RadzenDataGrid Grouping very slow on the first render
Fix #1684
2024-09-10 17:16:12 +03:00
Vladimir Enchev
4dfbd676af Fixed DatePicker logic for HoursStep, MinutesStep and SecondsStep 2024-09-10 08:24:19 +03:00
Vladimir Enchev
f72f8b3e39 Version updated 2024-09-09 12:36:34 +03:00
Vladimir Enchev
45cc6880f9 DataGrid should close other columns filter popups when FilterPopupRenderMode == PopupRenderMode.OnDemand 2024-09-09 11:04:35 +03:00
Vladimir Enchev
17281cd3b1 Numeric inputmode attribute can be defined using InputAttributes 2024-09-09 10:28:47 +03:00
Vladimir Enchev
332b452b56 Numeric inputmode attribute support fixed 2024-09-09 09:32:44 +03:00
Vladimir Enchev
c647515186 DataFilter IsEmoty/IsNotEmpty operators logic fixed 2024-09-08 15:15:54 +03:00
Vladimir Enchev
6faf0ed9b9 DataFilter 'Is Null' & 'Is Not Null' filter options do not produce correct filter via ToFilterString()
Fix #1682
2024-09-08 15:08:53 +03:00
Lynkle
fad024d9bb fix(FileInput): Modified FileInput.razor to handle rendering the preview of an image correctly when using byte[] as the TValue instead of string. Added a corresponding demo to highlight this. (#1680) 2024-09-08 08:29:45 +03:00
Vladimir Enchev
67718df278 Version updated 2024-09-06 09:26:34 +03:00
Christoph
273c3283c2 Add Reload method to RadzenTree (#1678)
* Added demo to illustrate the refresh problem with dynamic loading.

* Added RadzenTree.Reload public API.

* Documentation added.
2024-09-06 09:24:01 +03:00
Vladimir Enchev
aa7306ebd1 DropDownDataGrid OpenOnFocus logic fixed 2024-09-06 09:16:27 +03:00
Vladimir Enchev
56cb173ad5 DataGrid will not render colgroup if there are child columns
Fix #1674
2024-09-05 14:50:06 +03:00
Vladimir Enchev
174f0a9393 demo updated 2024-09-05 09:26:50 +03:00
Vladimir Enchev
a1dbc1a6fb DataGrid exception when trying to filter DateTimeOffset 2024-09-04 09:02:39 +03:00
Vladimir Enchev
d9de2ee0bc Version updated 2024-09-03 17:45:31 +03:00
Vladimir Enchev
cf1e0eda27 Fixed DataGrid string column will always apply Contains for initial filter 2024-09-03 17:40:37 +03:00
Vladimir Enchev
ccc82e5a61 DropDownDataGrid @bind-SelectedItem can cause endless loop in some cases 2024-09-02 14:08:43 +03:00
Vladimir Enchev
0859f939dd DataGrid CheckBoxList filter breaks cells value from enum description 2024-09-02 10:25:11 +03:00
Atanas Korchev
519c133c0c Update the descriptions and content of the RadzenHtmlEditor demos. 2024-09-02 10:22:48 +03:00
Atanas Korchev
9f62860821 The user can insert images and links in RadzenHtmlEditor by pressing Enter. 2024-09-02 09:51:24 +03:00
Atanas Korchev
238ed1ac2c The user can select an image in RadzenHtmlEditor by clicking it. Then use the Insert image tool to set its attributes. Closes #1209. 2024-09-02 09:51:24 +03:00
Vladimir Enchev
cd5903b358 Version updated 2024-09-02 09:08:33 +03:00
Vladimir Enchev
f78125c4fb DropDownDataGrid focus of selected item fixed 2024-09-02 09:06:54 +03:00
Atanas Korchev
6394241b9f Shared tooltips do not work in some cases. 2024-09-01 20:54:57 +03:00
Vladimir Enchev
d4dfc9bbab Fixed Slider with Min="1" change value with click 2024-08-31 09:32:27 +03:00
Vladimir Enchev
cf668be964 Version updated 2024-08-30 18:41:03 +03:00
Vladimir Enchev
6ef443d724 DropDownDataGrid Cannot read properties of undefined (reading 'classList') error fixed 2024-08-30 18:40:36 +03:00
Vladimir Enchev
75af217864 demo title fixed 2024-08-30 11:46:48 +03:00
Vladimir Enchev
7a7343c3c8 demo updated 2024-08-30 11:39:59 +03:00
Vladimir Enchev
18bfa8f562 DataGrid will allow mixed Simple and SimpleWithMenu modes per column 2024-08-30 11:38:46 +03:00
Vladimir Enchev
a76a0815a0 DataGrid column FilterMode property added
Fix #1672
2024-08-30 11:07:18 +03:00
Vladimir Enchev
332f384a65 DropDown selected item not highlighted on initial popup open 2024-08-29 09:52:38 +03:00
Vladimir Enchev
3c5e1216c8 Version updated 2024-08-29 09:17:42 +03:00
Vladimir Enchev
c7c11a1c1e DropDownDataGrid keyboard navigation fixed 2024-08-29 09:17:23 +03:00
Vladimir Enchev
0dd993c1d0 version updated 2024-08-28 10:09:36 +03:00
Vladimir Enchev
c977e9b59c DropDownDataGrid row not selected on initial selection 2024-08-28 10:09:16 +03:00
Vladimir Enchev
81055b5500 DataGrid composite column GroupFooterTemplate fixed 2024-08-28 09:53:00 +03:00
Vladimir Enchev
c8df446846 demo fixed 2024-08-28 09:15:36 +03:00
Vladimir Enchev
97ac4621b9 DataList ShowEmptyMessage disabled by default 2024-08-26 13:07:38 +03:00
Vladimir Enchev
9346c474cf DataGrid simple filter input autocomplete disabled 2024-08-26 13:06:24 +03:00
Vladimir Enchev
d9a55965d3 DataList EmptyMessage, EmptyTemplate and ShowEmptyMessage added
Fix #1666
2024-08-26 13:03:10 +03:00
218 changed files with 1904 additions and 5338 deletions

View File

@@ -119,12 +119,12 @@ namespace Radzen.Blazor.Tests
var component = ctx.RenderComponent<RadzenMask>();
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, false));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", false));
Assert.Contains(@$"autocomplete=""off""", component.Markup);
Assert.Contains(@$"aria-autocomplete=""none""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", true));
Assert.Contains(@$"autocomplete=""on""", component.Markup);
Assert.DoesNotContain(@$"aria-autocomplete", component.Markup);
@@ -135,7 +135,7 @@ namespace Radzen.Blazor.Tests
Assert.DoesNotContain(@$"aria-autocomplete", component.Markup);
component.Instance.DefaultAutoCompleteAttribute = "autocomplete-custom";
component.SetParametersAndRender(parameters => parameters.Add(p => p.AutoComplete, false));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", false));
Assert.Contains(@$"autocomplete=""autocomplete-custom""", component.Markup);
Assert.Contains(@$"aria-autocomplete=""none""", component.Markup);
@@ -148,22 +148,22 @@ namespace Radzen.Blazor.Tests
var component = ctx.RenderComponent<RadzenMask>();
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, false));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", false));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.On));
Assert.Contains(@$"autocomplete=""off""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.Off));
Assert.Contains(@$"autocomplete=""off""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.AdditionalName));
Assert.Contains(@$"autocomplete=""{AutoCompleteType.AdditionalName.GetAutoCompleteValue()}""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.Email));
Assert.Contains(@$"autocomplete=""{AutoCompleteType.Email.GetAutoCompleteValue()}""", component.Markup);

View File

@@ -60,6 +60,19 @@ namespace Radzen.Blazor.Tests
Assert.False(component.Instance.Validate(null));
}
[Fact]
public void Returns_True_If_Value_Is_Null_And_AllowNull_Is_True()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenNumericRangeValidatorTestDouble>();
component.SetParametersAndRender(parameters =>
{
component.SetParametersAndRender(parameters => parameters.Add(p => p.Min, 0).Add(p => p.Max, 10).Add(p => p.AllowNull, true));
});
Assert.True(component.Instance.Validate(null));
}
[Fact]
public void Returns_False_If_Value_Overflows()

View File

@@ -216,12 +216,12 @@ namespace Radzen.Blazor.Tests
var component = ctx.RenderComponent<RadzenNumeric<double>>();
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, false));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", false));
Assert.Contains(@$"autocomplete=""off""", component.Markup);
Assert.Contains(@$"aria-autocomplete=""none""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", true));
Assert.Contains(@$"autocomplete=""on""", component.Markup);
Assert.DoesNotContain(@$"aria-autocomplete", component.Markup);
@@ -232,7 +232,7 @@ namespace Radzen.Blazor.Tests
Assert.DoesNotContain(@$"aria-autocomplete", component.Markup);
component.Instance.DefaultAutoCompleteAttribute = "autocomplete-custom";
component.SetParametersAndRender(parameters => parameters.Add(p => p.AutoComplete, false));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", false));
Assert.Contains(@$"autocomplete=""autocomplete-custom""", component.Markup);
Assert.Contains(@$"aria-autocomplete=""none""", component.Markup);
@@ -245,22 +245,22 @@ namespace Radzen.Blazor.Tests
var component = ctx.RenderComponent<RadzenNumeric<double>>();
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, false));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", false));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.On));
Assert.Contains(@$"autocomplete=""off""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.Off));
Assert.Contains(@$"autocomplete=""off""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.BdayMonth));
Assert.Contains(@$"autocomplete=""{AutoCompleteType.BdayMonth.GetAutoCompleteValue()}""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.BdayYear));
Assert.Contains(@$"autocomplete=""{AutoCompleteType.BdayYear.GetAutoCompleteValue()}""", component.Markup);

View File

@@ -119,11 +119,11 @@ namespace Radzen.Blazor.Tests
var component = ctx.RenderComponent<RadzenPassword>();
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, false));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", false));
Assert.Contains(@$"autocomplete=""new-password""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", true));
Assert.Contains(@$"autocomplete=""on""", component.Markup);
@@ -139,22 +139,22 @@ namespace Radzen.Blazor.Tests
var component = ctx.RenderComponent<RadzenPassword>();
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, false));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", false));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.On));
Assert.Contains(@$"autocomplete=""new-password""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.Off));
Assert.Contains(@$"autocomplete=""off""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.CurrentPassword));
Assert.Contains(@$"autocomplete=""{AutoCompleteType.CurrentPassword.GetAutoCompleteValue()}""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.NewPassword));
Assert.Contains(@$"autocomplete=""{AutoCompleteType.NewPassword.GetAutoCompleteValue()}""", component.Markup);

View File

@@ -119,12 +119,12 @@ namespace Radzen.Blazor.Tests
var component = ctx.RenderComponent<RadzenTextBox>();
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, false));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", false));
Assert.Contains(@$"autocomplete=""off""", component.Markup);
Assert.Contains(@$"aria-autocomplete=""none""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", true));
Assert.Contains(@$"autocomplete=""on""", component.Markup);
Assert.DoesNotContain(@$"aria-autocomplete", component.Markup);
@@ -135,7 +135,7 @@ namespace Radzen.Blazor.Tests
Assert.DoesNotContain(@$"aria-autocomplete", component.Markup);
component.Instance.DefaultAutoCompleteAttribute = "autocomplete-custom";
component.SetParametersAndRender(parameters => parameters.Add(p => p.AutoComplete, false));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", false));
Assert.Contains(@$"autocomplete=""autocomplete-custom""", component.Markup);
Assert.Contains(@$"aria-autocomplete=""none""", component.Markup);
@@ -148,22 +148,22 @@ namespace Radzen.Blazor.Tests
var component = ctx.RenderComponent<RadzenTextBox>();
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, false));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", false));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.On));
Assert.Contains(@$"autocomplete=""off""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.Off));
Assert.Contains(@$"autocomplete=""off""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.AdditionalName));
Assert.Contains(@$"autocomplete=""{AutoCompleteType.AdditionalName.GetAutoCompleteValue()}""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.AddUnmatched("AutoComplete", true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.FamilyName));
Assert.Contains(@$"autocomplete=""{AutoCompleteType.FamilyName.GetAutoCompleteValue()}""", component.Markup);

View File

@@ -533,7 +533,7 @@ namespace Radzen.Blazor
{
return builder =>
{
var item = Items.FirstOrDefault(i => PropertyAccess.GetValue(i, CategoryProperty) == category);
var item = Items.FirstOrDefault(i => object.Equals(PropertyAccess.GetValue(i, CategoryProperty), category));
if (item != null)
{

View File

@@ -978,7 +978,7 @@ namespace Radzen
{
get
{
return _size != default(long) ? _size : source.Size;
return _size != default(long) ? _size : source != null ? source.Size : 0;
}
set
{
@@ -3113,7 +3113,7 @@ namespace Radzen
{
var type = data.GetType();
var arg = Expression.Parameter(typeof(object));
var body = Expression.Property(Expression.Convert(arg, type), propertyName);
var body = Expression.Convert(Expression.Property(Expression.Convert(arg, type), propertyName), typeof(T));
return Expression.Lambda<Func<object, T>>(body, arg).Compile();
}
@@ -3290,6 +3290,21 @@ namespace Radzen
return null;
}
/// <summary>
/// Gets the dynamic property expression when binding to IDictionary.
/// </summary>
/// <param name="name">The property name.</param>
/// <param name="type">The property type.</param>
/// <returns>Dynamic property expression.</returns>
public static string GetDynamicPropertyExpression(string name, Type type)
{
var isEnum = type.IsEnum || Nullable.GetUnderlyingType(type)?.IsEnum == true;
var typeName = isEnum ? "Enum" : (Nullable.GetUnderlyingType(type) ?? type).Name;
var typeFunc = $@"{typeName}{(!isEnum && Nullable.GetUnderlyingType(type) != null ? "?" : "")}";
return $@"{typeFunc}(it[""{name}""])";
}
}
/// <summary>

View File

@@ -16,13 +16,6 @@ namespace Radzen
/// </summary>
public class FormComponentWithAutoComplete<T> : FormComponent<T>
{
/// <summary>
/// Gets or sets a value indicating the browser built-in autocomplete is enabled.
/// </summary>
/// <value><c>true</c> if input automatic complete is enabled; otherwise, <c>false</c>.</value>
[Parameter]
public virtual bool AutoComplete { get; set; } = true;
/// <summary>
/// Gets or sets a value indicating the type of built-in autocomplete
/// the browser should use.
@@ -44,8 +37,8 @@ namespace Radzen
/// AutoCompleteType.</value>
public virtual string AutoCompleteAttribute
{
get => !AutoComplete ? DefaultAutoCompleteAttribute :
autoComplete as string ?? AutoCompleteType.GetAutoCompleteValue();
get => Attributes != null && Attributes.ContainsKey("AutoComplete") && $"{Attributes["AutoComplete"]}".ToLower() == "false" ? DefaultAutoCompleteAttribute :
Attributes != null && Attributes.ContainsKey("AutoComplete") ? Attributes["AutoComplete"] as string ?? AutoCompleteType.GetAutoCompleteValue() : AutoCompleteType.GetAutoCompleteValue();
}
/// <summary>
@@ -53,18 +46,11 @@ namespace Radzen
/// </summary>
public virtual string DefaultAutoCompleteAttribute { get; set; } = "off";
object autoComplete;
object ariaAutoComplete;
/// <inheritdoc />
public override async Task SetParametersAsync(ParameterView parameters)
{
parameters = parameters.TryGetValue(nameof(AutoComplete).ToLower(), out autoComplete) ?
ParameterView.FromDictionary(parameters
.ToDictionary().Where(i => i.Key != nameof(AutoComplete).ToLower()).ToDictionary(i => i.Key, i => i.Value)
.ToDictionary(i => i.Key, i => i.Value))
: parameters;
parameters = parameters.TryGetValue("aria-autocomplete", out ariaAutoComplete) ?
ParameterView.FromDictionary(parameters
.ToDictionary().Where(i => i.Key != "aria-autocomplete").ToDictionary(i => i.Key, i => i.Value)

View File

@@ -259,11 +259,21 @@ namespace Radzen
/// Converts a RadzenDataFilter to a Linq-compatibly filter string
/// </summary>
/// <typeparam name="T">The type that is being filtered</typeparam>
/// <param name="filter">The RadzenDataFilter component</param>
/// <param name="dataFilter">The RadzenDataFilter component</param>
/// <returns>A Linq-compatible filter string</returns>
public static string ToFilterString<T>(this RadzenDataFilter<T> filter)
public static string ToFilterString<T>(this RadzenDataFilter<T> dataFilter)
{
return CompositeFilterToFilterString<T>(filter.Filters, filter, filter.LogicalFilterOperator);
Func<CompositeFilterDescriptor, bool> canFilter = (c) => dataFilter.properties.Where(col => col.Property == c.Property).FirstOrDefault()?.FilterPropertyType != null &&
(!(c.FilterValue == null || c.FilterValue as string == string.Empty)
|| c.FilterOperator == FilterOperator.IsNotNull || c.FilterOperator == FilterOperator.IsNull
|| c.FilterOperator == FilterOperator.IsEmpty || c.FilterOperator == FilterOperator.IsNotEmpty)
&& c.Property != null;
if (dataFilter.Filters.Concat(dataFilter.Filters.SelectManyRecursive(i => i.Filters ?? Enumerable.Empty<CompositeFilterDescriptor>())).Where(canFilter).Any())
{
return CompositeFilterToFilterString<T>(dataFilter.Filters, dataFilter, dataFilter.LogicalFilterOperator);
}
return "";
}
/// <summary>
@@ -361,18 +371,45 @@ namespace Radzen
{
return $@"({property} == null ? """" : {property}){filterCaseSensitivityOperator} != ""{value}""{filterCaseSensitivityOperator}";
}
else if (columnFilterOperator == FilterOperator.IsNull)
{
return property + " == null";
}
else if (columnFilterOperator == FilterOperator.IsEmpty)
{
return property + @" == """"";
}
else if (columnFilterOperator == FilterOperator.IsNotEmpty)
{
return property + @" != """"";
}
else if (columnFilterOperator == FilterOperator.IsNotNull)
{
return property + @" != null";
}
}
else if (PropertyAccess.IsNumeric(columnType))
{
value = (string)Convert.ChangeType(column.FilterValue, typeof(string));
return $"{property} {linqOperator} {value}";
if (columnFilterOperator == FilterOperator.IsNull || columnFilterOperator == FilterOperator.IsNotNull)
{
return $"{property} {linqOperator} null";
}
else if (columnFilterOperator == FilterOperator.IsEmpty || columnFilterOperator == FilterOperator.IsNotEmpty)
{
return $@"{property} {linqOperator} """"";
}
else
{
return $"{property} {linqOperator} {value}";
}
}
else if (columnType == typeof(bool))
else if (columnType == typeof(bool) || columnType == typeof(bool?))
{
value = (string)Convert.ChangeType(column.FilterValue, typeof(string));
return $"{property} == {value}";
return $"{property} {linqOperator} {(columnFilterOperator == FilterOperator.IsNull || columnFilterOperator == FilterOperator.IsNotNull ? "null" : value)}";
}
else if (PropertyAccess.IsDate(columnType))
{
@@ -422,12 +459,13 @@ namespace Radzen
{
value = (string)Convert.ChangeType(column.FilterValue, typeof(string), CultureInfo.InvariantCulture);
}
if (!string.IsNullOrEmpty(value) || column.FilterOperator == FilterOperator.IsNotNull
|| column.FilterOperator == FilterOperator.IsNull
|| column.FilterOperator == FilterOperator.IsEmpty
|| column.FilterOperator == FilterOperator.IsNotEmpty)
{
return $"({property} {linqOperator} {value})";
return $"({property} {linqOperator} {(columnFilterOperator == FilterOperator.IsNull || columnFilterOperator == FilterOperator.IsNotNull ? "null" : value)})";
}
return "";
@@ -608,7 +646,8 @@ namespace Radzen
var value = IsEnumerable(column.FilterPropertyType) && column.FilterPropertyType != typeof(string)
? null
: (string)Convert.ChangeType(filterValue, typeof(string), CultureInfo.InvariantCulture);
: (string)Convert.ChangeType(filterValue is DateTimeOffset ?
((DateTimeOffset)filterValue).UtcDateTime : filterValue, typeof(string), CultureInfo.InvariantCulture);
if (column.Grid.FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive && column.FilterPropertyType == typeof(string))
{
@@ -1043,7 +1082,8 @@ namespace Radzen
else
{
if (filter.Property == null || filter.FilterOperator == null || (filter.FilterValue == null &&
filter.FilterOperator != FilterOperator.IsNull && filter.FilterOperator != FilterOperator.IsNotNull))
filter.FilterOperator != FilterOperator.IsNull && filter.FilterOperator != FilterOperator.IsNotNull &&
filter.FilterOperator != FilterOperator.IsEmpty && filter.FilterOperator != FilterOperator.IsNotEmpty))
{
return;
}

View File

@@ -8,7 +8,7 @@
<IsPackable>true</IsPackable>
<PackageId>Radzen.Blazor</PackageId>
<Product>Radzen.Blazor</Product>
<Version>5.1.3</Version>
<Version>5.2.1</Version>
<Copyright>Radzen Ltd.</Copyright>
<Authors>Radzen Ltd.</Authors>
<Description>Radzen Blazor is a set of 90+ free native Blazor UI controls packed with DataGrid, Scheduler, Charts and robust theming including Material design and Fluent UI.</Description>

View File

@@ -83,6 +83,8 @@
<div class="rz-data-grid-data" tabindex="-1">
<table class="rz-grid-table rz-grid-table-fixed @(AllowAlternatingRows ? "rz-grid-table-striped" : "") @(allColumns.Any(c => c.Parent != null) ? "rz-grid-table-composite" : "") @(getGridLinesCSSClass())">
@if(allColumns.All(c => c.Parent == null))
{
<colgroup>
@if (ShowGroupExpandColumn)
{
@@ -100,6 +102,7 @@
<col id=@(getColumnUniqueId(visibleColumns.IndexOf(column)) + "-col") style="@column.GetStyle(false, false, true)">
}
</colgroup>
}
<thead>
@for (var i = 0; i < deepestChildColumnLevel + 1; i++)
{
@@ -143,7 +146,7 @@
}
</tr>
}
@if (AllowFiltering && (FilterMode == FilterMode.Simple || FilterMode == FilterMode.SimpleWithMenu) && columns.Where(column => column.Filterable && (!string.IsNullOrEmpty(column.GetFilterProperty()) || column.FilterTemplate != null)).Any())
@if (AllowFiltering && (visibleColumns.Any(c => c.FilterMode == FilterMode.Simple || c.FilterMode == FilterMode.SimpleWithMenu) || FilterMode == FilterMode.Simple || FilterMode == FilterMode.SimpleWithMenu) && columns.Where(column => column.Filterable && (!string.IsNullOrEmpty(column.GetFilterProperty()) || column.FilterTemplate != null)).Any())
{
<tr @onkeydown:stopPropagation>
@if (ShowGroupExpandColumn)
@@ -163,6 +166,7 @@
}
@foreach (var column in visibleColumns)
{
var filterMode = column.FilterMode ?? FilterMode;
<th colspan="@column.GetColSpan()" class="@($"rz-unselectable-text {getFrozenColumnClass(column, visibleColumns)} {column.HeaderCssClass}")" scope="col" style="@column.GetStyle(true, true)">
@if (AllowFiltering && column.Filterable && column.Columns == null && (!string.IsNullOrEmpty(column.GetFilterProperty()) || column.FilterTemplate != null))
{
@@ -177,7 +181,7 @@
<span class="rz-cell-filter-label" style="height:35px; width:100%;" onclick="event.preventDefault()">
@if (PropertyAccess.IsDate(column.FilterPropertyType))
{
if (FilterMode == FilterMode.Simple)
if (filterMode == FilterMode.Simple)
{
<button aria-label="@FilterToggleAriaLabel" class="rz-button rz-button-md rz-button-icon-only rz-variant-flat rz-base rz-shade-default" onclick="@($"Radzen.togglePopup(this.parentNode, '{PopupID}{column.GetFilterProperty()}')")">
<i class="rzi">date_range</i>
@@ -297,7 +301,7 @@
}
else if (PropertyAccess.IsNumeric(column.FilterPropertyType))
{
if (FilterMode == FilterMode.SimpleWithMenu)
if (filterMode == FilterMode.SimpleWithMenu)
{
<RadzenDataGridFilterMenu Grid="@this" Column="@column" />
}
@@ -311,11 +315,11 @@
}
else
{
if (FilterMode == FilterMode.SimpleWithMenu)
if (filterMode == FilterMode.SimpleWithMenu)
{
<RadzenDataGridFilterMenu Grid="@this" Column="@column" />
}
<input aria-label=@(column.Title + FilterValueArialLabel + column.GetFilterValue()) disabled=@(!column.CanSetFilterValue()) id="@(getFilterInputId(column))" @onchange="@((args) => OnFilter(args, column))" @onkeydown="@((args) => OnFilterKeyPress(args, column))" value="@column.GetFilterValue()" type="text" placeholder="@column.GetFilterPlaceholder()" class="rz-textbox" style="width: 100%;" />
<input autocomplete="off" aria-label=@(column.Title + FilterValueArialLabel + column.GetFilterValue()) disabled=@(!column.CanSetFilterValue()) id="@(getFilterInputId(column))" @onchange="@((args) => OnFilter(args, column))" @onkeydown="@((args) => OnFilterKeyPress(args, column))" value="@column.GetFilterValue()" type="text" placeholder="@column.GetFilterPlaceholder()" class="rz-textbox" style="width: 100%;" />
@if (column.GetFilterValue() != null && filters.Any(d => d.Property == column.GetFilterProperty()))
{
<i @onclick="@((args) => ClearFilter(column))" class="rzi rz-cell-filter-clear" style="position:absolute;inset-inline-end:10px;">close</i>

View File

@@ -140,8 +140,8 @@ namespace Radzen.Blazor
if (Groups.Any())
{
query = view.AsQueryable().OrderBy(Groups.Any() ? string.Join(',', Groups.Select(g => $"{(typeof(TItem) == typeof(object) ? g.Property : "np(" + g.Property + ")")}")) : "it");
_groupedPagedView = query.GroupByMany(Groups.Any() ? Groups.Select(g => $"{(typeof(TItem) == typeof(object) ? g.Property : "np(" + g.Property + ")")}").ToArray() : new string[] { "it" }).ToList();
query = view.AsQueryable().OrderBy(DynamicLinqCustomTypeProvider.ParsingConfig, Groups.Any() ? string.Join(',', Groups.Select(g => $"{(typeof(TItem) == typeof(object) ? g.Property : "np(" + g.Property + ")")}")) : "it");
_groupedPagedView = query.GroupByMany(DynamicLinqCustomTypeProvider.ParsingConfig, Groups.Any() ? Groups.Select(g => $"{(typeof(TItem) == typeof(object) ? g.Property : "np(" + g.Property + ")")}").ToArray() : new string[] { "it" }).ToList();
totalItemsCount = await Task.FromResult(_groupedPagedView.Count());
}
@@ -341,7 +341,7 @@ namespace Radzen.Blazor
var orderBy = GetOrderBy();
var query = Groups.Count(g => g.SortOrder == null) == Groups.Count || !string.IsNullOrEmpty(orderBy) ? View : View.OrderBy(DynamicLinqCustomTypeProvider.ParsingConfig, string.Join(',', Groups.Select(g => $"{(typeof(TItem) == typeof(object) ? g.Property : "np(" + g.Property + ")")} {(g.SortOrder == null ? "" : g.SortOrder == SortOrder.Ascending ? " asc" : " desc")}")));
var v = (AllowPaging && !LoadData.HasDelegate ? query.Skip(skip).Take(PageSize) : query).ToList().AsQueryable();
_groupedPagedView = v.GroupByMany(Groups.Select(g => $"{(typeof(TItem) == typeof(object) ? g.Property : "np(" + g.Property + ")")}").ToArray()).ToList();
_groupedPagedView = v.GroupByMany(DynamicLinqCustomTypeProvider.ParsingConfig, Groups.Select(g => $"{(typeof(TItem) == typeof(object) ? g.Property : "np(" + g.Property + ")")}").ToArray()).ToList();
}
return _groupedPagedView;
}
@@ -483,12 +483,21 @@ namespace Radzen.Blazor
}
}
/// <summary>
/// Gets or sets key down callback.
/// </summary>
/// <value>The key down callback.</value>
[Parameter]
public EventCallback<KeyboardEventArgs> KeyDown { get; set; }
/// <summary>
/// Handles the <see cref="E:KeyDown" /> event.
/// </summary>
/// <param name="args">The <see cref="KeyboardEventArgs"/> instance containing the event data.</param>
protected virtual async Task OnKeyDown(KeyboardEventArgs args)
{
await KeyDown.InvokeAsync(args);
var key = args.Code != null ? args.Code : args.Key;
if (key == "ArrowDown" || key == "ArrowUp" || key == "ArrowLeft" || key == "ArrowRight")

View File

@@ -38,6 +38,19 @@ namespace Radzen.Blazor
[CascadingParameter]
public RadzenDataGridColumn<TItem> Parent { get; set; }
/// <summary>
/// Specifies wether CheckBoxList filter list virtualization is enabled. Set to <c>true</c> by default.
/// </summary>
[Parameter]
public bool AllowCheckBoxListVirtualization { get; set; } = true;
/// <summary>
/// Gets or sets the column filter mode.
/// </summary>
/// <value>The column filter mode.</value>
[Parameter]
public FilterMode? FilterMode { get; set; }
internal void RemoveColumn(RadzenDataGridColumn<TItem> column)
{
if (Grid.childColumns.Contains(column))
@@ -120,7 +133,7 @@ namespace Radzen.Blazor
{
Grid.AddColumn(this);
var canSetFilterPropertyType = Grid.FilterMode == FilterMode.CheckBoxList && FilterTemplate == null;
var canSetFilterPropertyType = (FilterMode ?? Grid.FilterMode) == Radzen.FilterMode.CheckBoxList && FilterTemplate == null;
if (canSetFilterPropertyType)
{
@@ -567,7 +580,9 @@ namespace Radzen.Blazor
{
var value = propertyValueGetter != null && !string.IsNullOrEmpty(Property) && !Property.Contains('.') ? propertyValueGetter(item) : !string.IsNullOrEmpty(Property) ? PropertyAccess.GetValue(item, Property) : "";
if ((PropertyAccess.IsEnum(FilterPropertyType) || PropertyAccess.IsNullableEnum(FilterPropertyType)) && value != null)
if ((PropertyAccess.IsEnum(FilterPropertyType) || PropertyAccess.IsNullableEnum(FilterPropertyType) ||
((FilterMode ?? Grid.FilterMode) == Radzen.FilterMode.CheckBoxList && (value as Enum) != null)) && value != null)
{
var enumValue = value as Enum;
if (enumValue != null)
@@ -945,9 +960,9 @@ namespace Radzen.Blazor
}
}
if (parameters.DidParameterChange(nameof(FilterOperator), FilterOperator))
if (parameters.DidParameterChange(nameof(FilterOperator), FilterOperator) || _filterOperator != null)
{
filterOperator = parameters.GetValueOrDefault<FilterOperator>(nameof(FilterOperator));
filterOperator = _filterOperator ?? parameters.GetValueOrDefault<FilterOperator>(nameof(FilterOperator));
}
if (parameters.DidParameterChange(nameof(SecondFilterValue), SecondFilterValue))
@@ -1140,12 +1155,23 @@ namespace Radzen.Blazor
LogicalFilterOperator = default(LogicalFilterOperator);
}
FilterOperator? _filterOperator;
/// <summary>
/// Gets or sets the filter operator.
/// </summary>
/// <value>The filter operator.</value>
[Parameter]
public FilterOperator FilterOperator { get; set; }
public FilterOperator FilterOperator
{
get
{
return _filterOperator ?? FilterOperator.Equals;
}
set
{
_filterOperator = value;
}
}
/// <summary>
/// Gets or sets the second filter operator.

View File

@@ -0,0 +1,61 @@
@typeparam TItem
@if (RowIndex == Column.GetLevel())
{
<td rowspan="@(Column.GetRowSpan())" colspan="@(Column.GetColSpan())" @attributes="@Attributes" class="@CssClass" scope="col" style="@GetStyle()">
<span class="rz-column-footer">
@if (Column.GroupFooterTemplate != null)
{
@Column.GroupFooterTemplate(Group)
}
</span>
</td>
}
else
{
@foreach(var column in Grid.childColumns.Where(c => c.GetVisible() && c.Parent == Column))
{
<RadzenDataGridGroupFooterCell Group="@Group" RowIndex="@RowIndex" Grid="@Grid" Column="@column" Style="@column.GetStyle(true, true)"
CssClass="@($"{Column.GroupFooterCssClass} {Grid.getFrozenColumnClass(column, Grid.ColumnsCollection.Where(c => c.GetVisible()).ToList())} {Grid.getCompositeCellCSSClass(column)}")"
Attributes="@(Attributes)" />
}
}
@code {
[Parameter(CaptureUnmatchedValues = true)]
public IReadOnlyDictionary<string, object> Attributes { get; set; }
[Parameter]
public Group Group { get; set; }
[Parameter]
public RadzenDataGridColumn<TItem> Column { get; set; }
[Parameter]
public int RowIndex { get; set; }
[Parameter]
public RadzenDataGrid<TItem> Grid { get; set; }
[Parameter]
public string CssClass { get; set; }
[Parameter]
public string Style { get; set; }
private string GetStyle()
{
var styles = new List<string>() { Column.GetStyle(true, true), Style };
if (Attributes?.TryGetValue("style", out var styleAttribute) == true)
{
styles.Add(Convert.ToString(styleAttribute));
}
var finalStyle = string.Join(";",
styles
.Select(x => x?.Trim().TrimEnd(';'))
.Where(x => !string.IsNullOrEmpty(x))
);
return finalStyle;
}
}

View File

@@ -1,33 +1,33 @@
@typeparam TItem
@using System.Linq.Dynamic.Core
<tr>
@if (Grid.Template != null && Grid.ShowExpandColumn)
{
@if (Grid.ShowGroupExpandColumn)
{
<th class="rz-col-icon rz-unselectable-text" scope="col">
<span class="rz-column-title"></span>
</th>
}
}
@for(var i = 0; i < GetLevel(); i++)
{
<td class="rz-col-icon">
<span class="rz-column-title"></span>
</td>
}
@foreach (var column in Columns)
{
<td class="@($" {column.GroupFooterCssClass} {Grid.getFrozenColumnClass(column, Columns)}".Trim())" style="@column.GetStyle(true, true)">
<span class="rz-column-footer">
@if (column.GroupFooterTemplate != null)
@for (var i = 0; i < Grid.deepestChildColumnLevel + 1; i++)
{
<tr>
@if (i == 0) // Only add the th elements for the first row
{
@if (Grid.Template != null && Grid.ShowExpandColumn)
{
@if (Grid.ShowGroupExpandColumn)
{
@column.GroupFooterTemplate(Group)
<th class="rz-col-icon rz-unselectable-text" scope="col">
<span class="rz-column-title"></span>
</th>
}
</span>
</td>
}
</tr>
}
}
@for (var j = 0; j < GetLevel(); j++)
{
<td class="rz-col-icon">
<span class="rz-column-title"></span>
</td>
}
@foreach (var column in Columns)
{
<RadzenDataGridGroupFooterCell Group="@Group" RowIndex="@i" Grid="@Grid" Column="@column" CssClass="@($"{column.GroupFooterCssClass} {Grid.getFrozenColumnClass(column, Columns)} {Grid.getCompositeCellCSSClass(column)}".Trim())" />
}
</tr>
}
@code {
[Parameter]
public IList<RadzenDataGridColumn<TItem>> Columns { get; set; }

View File

@@ -58,7 +58,8 @@
@onmousedown:preventDefault="true"
@onmousedown=@StartColumnResize @onmouseup=@StopColumnResize>&nbsp;</div>
}
@if (Grid.AllowFiltering && Column.Filterable && (Grid.FilterMode == FilterMode.Advanced || Grid.FilterMode == FilterMode.CheckBoxList))
@{var filterMode = Column.FilterMode ?? Grid.FilterMode;}
@if (Grid.AllowFiltering && Column.Filterable && (filterMode == FilterMode.Advanced || filterMode == FilterMode.CheckBoxList))
{
<i @ref=@filterButton @onclick:stopPropagation="true" @onmousedown=@ToggleFilter
class="@getFilterIconCss(Column)" onclick=@getFilterOpen() @onclick:preventDefault="true">
@@ -75,7 +76,7 @@
else
{
<form id="@($"{getColumnPopupID()}-form")" @onsubmit="@(args => ApplyFilter())" class="rz-grid-filter">
@if(Grid.FilterMode == FilterMode.Advanced)
@if (filterMode == FilterMode.Advanced)
{
<span class="rz-grid-filter-label">@Grid.FilterText</span>
<RadzenDropDown InputAttributes="@(new Dictionary<string,object>(){ { "aria-label", Grid.FilterOperatorArialLabel + Column.GetFilterOperatorText(Column.GetSecondFilterOperator()) }})"
@@ -147,7 +148,7 @@
}
else
{
<RadzenListBox AllowVirtualization="true" AllowClear="true" Multiple="true" Style="height: 300px"
<RadzenListBox AllowVirtualization="@Column.AllowCheckBoxListVirtualization" AllowClear="true" Multiple="true" Style="height: 300px"
TValue="IEnumerable<object>" Value=@Column.GetFilterValue() Change="@ListBoxChange"
Data=@filterValues Count=@filterValuesCount LoadData="@LoadFilterValues"
AllowFiltering="@(!string.IsNullOrEmpty(Column.GetFilterProperty()) && PropertyAccess.GetPropertyType(typeof(TItem), Column.GetFilterProperty()) == typeof(string))"
@@ -267,6 +268,11 @@ else
}
filterValues = query;
if (!Column.AllowCheckBoxListVirtualization)
{
await InvokeAsync(StateHasChanged);
}
}
}
@@ -306,6 +312,11 @@ else
if (Grid.FilterPopupRenderMode == PopupRenderMode.OnDemand)
{
await popup.ToggleAsync(filterButton);
Grid.allColumns
.Where(c => c != Column && c.headerCell != null)
.Select(c => c.headerCell).ToList()
.ForEach(cell => InvokeAsync(cell.CloseFilter));
}
}

View File

@@ -10,15 +10,29 @@
}
@if (Data != null)
{
@if (!WrapItems)
{
@DrawDataListRows()
}
else
@if (!ShowEmptyMessage || Count > 0 && (AllowVirtualization ? Count > 0 : true) || LoadData.HasDelegate && Data.Count() > 0)
{
@if (!WrapItems)
{
@DrawDataListRows()
}
else
{
<div class="rz-g">
@DrawDataListRows()
</div>
}
}
else
{
@if (EmptyTemplate != null)
{
@EmptyTemplate
}
else
{
<span style="white-space: normal">@EmptyText</span>
}
}
}
@if (IsLoading)

View File

@@ -38,6 +38,37 @@ namespace Radzen.Blazor
return "rz-datalist-content";
}
/// <summary>
/// Gets or sets a value indicating whether DataList should show empty message.
/// </summary>
[Parameter]
public bool ShowEmptyMessage { get; set; }
private string _emptyText = "No records to display.";
/// <summary>
/// Gets or sets the empty text shown when Data is empty collection.
/// </summary>
/// <value>The empty text.</value>
[Parameter]
public string EmptyText
{
get { return _emptyText; }
set
{
if (value != _emptyText)
{
_emptyText = value;
}
}
}
/// <summary>
/// Gets or sets the empty template shown when Data is empty collection.
/// </summary>
/// <value>The empty template.</value>
[Parameter]
public RenderFragment EmptyTemplate { get; set; }
/// <summary>
/// Gets or sets a value indicating whether to wrap items.
/// </summary>

View File

@@ -45,7 +45,11 @@
Change="@((args) => { SetMonth(int.Parse(args.ToString())); })"/>
<RadzenDropDown @ref="yearDropDown" class="rz-calendar-year-dropdown" TabIndex="@TabIndex"
TValue="int" Value="@CurrentDate.Year" Disabled="@Disabled" Data="@years" TextProperty="Name" ValueProperty="Value"
Change="@((args) => { SetYear(int.Parse(args.ToString())); })"/>
Change="@((args) => { SetYear(int.Parse(args.ToString())); })">
<Template>
@Culture.Calendar.GetYear(new DateTime(context.Value,1,1))
</Template>
</RadzenDropDown>
</div>
</div>
@if(ShowDays)

View File

@@ -170,9 +170,9 @@ namespace Radzen.Blazor
if (v < 0)
{
newHour = 23;
newMinute = 59;
newSecond = 59;
newHour = string.IsNullOrEmpty(HoursStep) ? 23 : 0;
newMinute = string.IsNullOrEmpty(MinutesStep) ? 59 : 0;
newSecond = string.IsNullOrEmpty(SecondsStep) ? 59 : 0;
}
var newValue = new DateTime(CurrentDate.Year, CurrentDate.Month, CurrentDate.Day, newHour > 23 || newHour < 0 ? 0 : newHour, newMinute, newSecond);

View File

@@ -134,7 +134,7 @@ namespace Radzen.Blazor
await JSRuntime.InvokeVoidAsync(OpenOnFocus ? "Radzen.openPopup" : "Radzen.togglePopup", Element, PopupID, true);
await JSRuntime.InvokeVoidAsync("Radzen.focusElement", isFilter ? UniqueID : SearchID);
if (list != null)
if (list != null && selectedIndex != -1)
{
await JSRuntime.InvokeVoidAsync("Radzen.selectListItem", search, list, selectedIndex);
}

View File

@@ -352,19 +352,32 @@ namespace Radzen.Blazor
/// </summary>
/// <param name="firstRender">if set to <c>true</c> [first render].</param>
/// <returns>Task.</returns>
protected override Task OnAfterRenderAsync(bool firstRender)
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
if(Visible && LoadData.HasDelegate && Data == null)
{
LoadData.InvokeAsync(new Radzen.LoadDataArgs() { Skip = 0, Top = PageSize, Filter = searchText });
await LoadData.InvokeAsync(new Radzen.LoadDataArgs() { Skip = 0, Top = PageSize, Filter = searchText });
}
StateHasChanged();
if (!Multiple && grid != null && SelectedItem != null)
{
var items = (LoadData.HasDelegate ? Data != null ? Data : Enumerable.Empty<object>() : (pagedData != null ? pagedData : Enumerable.Empty<object>())).OfType<object>().ToList();
if (items.Any())
{
selectedIndex = items.IndexOf(SelectedItem);
if (selectedIndex >= 0)
{
await JSRuntime.InvokeAsync<int[]>("Radzen.focusTableRow", grid.GridId(), "ArrowDown", selectedIndex - 1, null);
}
}
}
}
return base.OnAfterRenderAsync(firstRender);
await base.OnAfterRenderAsync(firstRender);
}
/// <summary>
@@ -542,21 +555,32 @@ namespace Radzen.Blazor
{
if (!Multiple)
{
bool raiseChange = false;
if (!string.IsNullOrEmpty(ValueProperty))
{
var item = Query.Where(DynamicLinqCustomTypeProvider.ParsingConfig, $@"{ValueProperty} == @0", value).FirstOrDefault();
if (item != null)
if (item != null && SelectedItem != item)
{
SelectedItem = item;
raiseChange = true;
}
}
else
{
SelectedItem = internalValue;
if (SelectedItem != internalValue)
{
SelectedItem = internalValue;
raiseChange = true;
}
}
if (raiseChange)
{
SelectedItemChanged.InvokeAsync(SelectedItem);
selectedItems.Clear();
selectedItems.Add(SelectedItem);
}
SelectedItemChanged.InvokeAsync(SelectedItem);
selectedItems.Clear();
selectedItems.Add(SelectedItem);
}
else
{
@@ -695,10 +719,7 @@ namespace Radzen.Blazor
}
}
if (!Multiple)
{
await JSRuntime.InvokeVoidAsync("Radzen.closePopup", PopupID);
}
await CloseAndFocus();
}
}
else if (args.AltKey && key == "ArrowDown")
@@ -868,18 +889,27 @@ namespace Radzen.Blazor
async Task OnRowSelect(object item)
{
if (!Disabled && !Multiple)
{
await JSRuntime.InvokeVoidAsync("Radzen.closePopup", PopupID);
}
await JSRuntime.InvokeVoidAsync("Radzen.focusElement", UniqueID);
await CloseAndFocus();
if (AllowRowSelectOnRowClick)
{
await SelectItem(item);
}
}
async Task CloseAndFocus()
{
if (!Disabled && !Multiple)
{
await JSRuntime.InvokeVoidAsync("Radzen.closePopup", PopupID);
}
var of = OpenOnFocus;
OpenOnFocus = false;
await JSRuntime.InvokeVoidAsync("Radzen.focusElement", UniqueID);
OpenOnFocus = of;
}
private async Task OnChipRemove(object item)

View File

@@ -23,7 +23,7 @@
<div>
@if (IsImage)
{
<img style="@ImageStyle" src="@Value" @onclick="@OnImageClick" alt="@ImageAlternateText" />
<img style="@ImageStyle" src="@ImageValue" @onclick="@OnImageClick" alt="@ImageAlternateText" />
}
</div>
<div>

View File

@@ -100,6 +100,23 @@ namespace Radzen.Blazor
}
}
private string ImageValue
{
get
{
if (Value == null)
{
return string.Empty;
}
else if (Value is byte[] bytes)
{
return System.Text.Encoding.Default.GetString(bytes);
}
return Value.ToString();
}
}
async Task OnChange()
{
string uploadValue;

View File

@@ -235,6 +235,8 @@ namespace Radzen.Blazor
{
htmlChanged = false;
_value = Html;
await ValueChanged.InvokeAsync(Html);
if (FieldIdentifier.FieldName != null)
@@ -416,5 +418,41 @@ namespace Radzen.Blazor
JSRuntime.InvokeVoidAsync("Radzen.destroyEditor", ContentEditable);
}
}
/// <summary>
/// Gets or sets the callback which when a file is uploaded.
/// </summary>
/// <value>The complete callback.</value>
[Parameter]
public EventCallback<UploadCompleteEventArgs> UploadComplete { get; set; }
internal async Task RaiseUploadComplete(UploadCompleteEventArgs args)
{
await UploadComplete.InvokeAsync(args);
}
/// <summary>
/// Invoked by interop when the upload is complete.
/// </summary>
[JSInvokable("OnUploadComplete")]
public async Task OnUploadComplete(string response)
{
System.Text.Json.JsonDocument doc = null;
if (!string.IsNullOrEmpty(response))
{
try
{
doc = System.Text.Json.JsonDocument.Parse(response);
}
catch (System.Text.Json.JsonException)
{
//
}
}
await UploadComplete.InvokeAsync(new UploadCompleteEventArgs() { RawResponse = response, JsonResponse = doc });
}
}
}

View File

@@ -15,44 +15,57 @@
Attributes = await Editor.GetSelectionAttributes<ImageAttributes>("img", new[] {"src", "alt", "width", "height"});
var result = await DialogService.OpenAsync(Title, ds =>
@<div class="rz-html-editor-dialog">
<div class="rz-html-editor-dialog-item">
<label>@SelectText</label>
@if (Editor.UploadUrl != null)
{
<RadzenUpload ChooseText=@UploadChooseText @ref=@FileUpload Url=@Editor.UploadUrl Auto="false" Accept="image/*"
style="width: 100%" Complete="OnUploadComplete" Error="OnUploadError">
@foreach (var header in uploadHeaders)
{
<RadzenUploadHeader Name=@header.Key Value=@header.Value />
}
var result = await DialogService.OpenAsync(Title, ds => @<div class="rz-html-editor-dialog">
<RadzenTemplateForm TItem="ImageAttributes" Data="@Attributes" Submit="OnSubmit">
<div class="rz-html-editor-dialog-item">
<label>@SelectText</label>
@if (Editor.UploadUrl != null)
{
<RadzenUpload ChooseText=@UploadChooseText @ref=@FileUpload Url=@Editor.UploadUrl Auto="false" Accept="image/*"
style="width: 100%" Complete="OnUploadComplete" Error="OnUploadError">
@foreach (var header in uploadHeaders)
{
<RadzenUploadHeader Name=@header.Key Value=@header.Value />
}
</RadzenUpload>
} else {
<RadzenFileInput Accept="image/*" ChooseText=@UploadChooseText @bind-Value=@Attributes.Src style="width: 100%" />
}
</div>
<div class="rz-html-editor-dialog-item">
<label>@WidthText</label>
<RadzenTextBox @bind-Value=@Attributes.Width style="width: 100%" />
</div>
<div class="rz-html-editor-dialog-item">
<label>@HeightText</label>
<RadzenTextBox @bind-Value=@Attributes.Height style="width: 100%" />
</div>
<div class="rz-html-editor-dialog-item">
<label>@UrlText</label>
<RadzenTextBox @bind-Value=@Attributes.Src style="width: 100%" />
</div>
<div class="rz-html-editor-dialog-item">
<label>@AltText</label>
<RadzenTextBox @bind-Value=@Attributes.Alt style="width: 100%" />
</div>
<div class="rz-html-editor-dialog-buttons">
<RadzenButton Text=@OkText Click="OnSubmit" />
<RadzenButton Text=@CancelText Click="()=> ds.Close(false)" ButtonStyle="ButtonStyle.Secondary" />
</div>
} else {
<RadzenFileInput Accept="image/*" ChooseText=@UploadChooseText @bind-Value=@Attributes.Src style="width: 100%" />
}
</div>
@if (ShowWidth)
{
<div class="rz-html-editor-dialog-item">
<label>@WidthText</label>
<RadzenTextBox @bind-Value=@Attributes.Width style="width: 100%" />
</div>
}
@if (ShowHeight)
{
<div class="rz-html-editor-dialog-item">
<label>@HeightText</label>
<RadzenTextBox @bind-Value=@Attributes.Height style="width: 100%" />
</div>
}
@if (ShowSrc)
{
<div class="rz-html-editor-dialog-item">
<label>@UrlText</label>
<RadzenTextBox @bind-Value=@Attributes.Src style="width: 100%" />
</div>
}
@if (ShowAlt)
{
<div class="rz-html-editor-dialog-item">
<label>@AltText</label>
<RadzenTextBox @bind-Value=@Attributes.Alt style="width: 100%" />
</div>
}
<div class="rz-html-editor-dialog-buttons">
<RadzenButton Text=@OkText ButtonType="ButtonType.Submit" />
<RadzenButton Text=@CancelText Click="()=> ds.Close(false)" ButtonStyle="ButtonStyle.Secondary" />
</div>
</RadzenTemplateForm>
</div>
);
);
}
}

View File

@@ -81,6 +81,30 @@ namespace Radzen.Blazor
[Parameter]
public string HeightText { get; set; } = "Image Height";
/// <summary>
/// Specifies whether to show the image width section. Set it to false to hide it. Default value is true.
/// </summary>
[Parameter]
public bool ShowWidth { get; set; } = true;
/// <summary>
/// Specifies whether to show the image height section. Set it to false to hide it. Default value is true.
/// </summary>
[Parameter]
public bool ShowHeight { get; set; } = true;
/// <summary>
/// Specifies whether to show the web address section. Set it to false to hide it. Default value is true.
/// </summary>
[Parameter]
public bool ShowSrc { get; set; } = true;
/// <summary>
/// Specifies whether to show the alternative text section. Set it to false to hide it. Default value is true.
/// </summary>
[Parameter]
public bool ShowAlt { get; set; } = true;
ImageAttributes Attributes { get; set; }
RadzenUpload FileUpload { get; set; }
@@ -107,6 +131,8 @@ namespace Radzen.Blazor
{
DialogService.Close(true);
}
await Editor.RaiseUploadComplete(args);
}
async Task OnUploadError(UploadErrorEventArgs args)

View File

@@ -20,28 +20,29 @@
blank = true;
}
var result = await DialogService.OpenAsync(Title, ds =>
@<div class="rz-html-editor-dialog">
<div class="rz-html-editor-dialog-item">
<label>@UrlText</label>
<RadzenTextBox @bind-Value=@attributes.Href style="width: 100%" />
</div>
@if (string.IsNullOrWhiteSpace(attributes.InnerHtml) || attributes.InnerHtml == "<br>")
{
<div class="rz-html-editor-dialog-item">
<label>@LinkText</label>
<RadzenTextBox @bind-Value=@attributes.InnerText style="width: 100%" />
</div>
}
<div class="rz-html-editor-dialog-item">
<RadzenCheckBox @bind-Value=@blank />
<label>@OpenInNewWindowText</label>
</div>
<div class="rz-html-editor-dialog-buttons">
<RadzenButton Text=@OkText Click="()=> ds.Close(true)" />
<RadzenButton Text=@CancelText Click="()=> ds.Close(false)" ButtonStyle="ButtonStyle.Secondary" />
</div>
</div>);
var result = await DialogService.OpenAsync(Title, ds => @<div class="rz-html-editor-dialog">
<RadzenTemplateForm TItem="LinkAttributes" Data="@attributes" Submit="() => ds.Close(true)">
<div class="rz-html-editor-dialog-item">
<label>@UrlText</label>
<RadzenTextBox @bind-Value=@attributes.Href style="width: 100%" />
</div>
@if (string.IsNullOrWhiteSpace(attributes.InnerHtml) || attributes.InnerHtml == "<br>")
{
<div class="rz-html-editor-dialog-item">
<label>@LinkText</label>
<RadzenTextBox @bind-Value=@attributes.InnerText style="width: 100%" />
</div>
}
<div class="rz-html-editor-dialog-item">
<RadzenCheckBox @bind-Value=@blank />
<label>@OpenInNewWindowText</label>
</div>
<div class="rz-html-editor-dialog-buttons">
<RadzenButton Text=@OkText ButtonType="ButtonType.Submit" />
<RadzenButton Text=@CancelText Click="()=> ds.Close(false)" ButtonStyle="ButtonStyle.Secondary" />
</div>
</RadzenTemplateForm>
</div>);
await Editor.RestoreSelectionAsync();
@@ -58,6 +59,5 @@
await Editor.ExecuteCommandAsync("insertHTML", html.ToString());
}
}
}

View File

@@ -8,7 +8,7 @@
@if (Visible)
{
<span @ref="@Element" style="@Style" @attributes="Attributes" class="@GetCssClass()" id="@GetId()">
<input @ref="@input" @attributes="InputAttributes" type="text" inputmode="decimal" name="@Name" disabled="@Disabled" readonly="@ReadOnly"
<input @ref="@input" inputmode="decimal" @attributes="InputAttributes" type="text" name="@Name" disabled="@Disabled" readonly="@ReadOnly"
class="@GetInputCssClass()" tabindex="@(Disabled ? "-1" : $"{TabIndex}")" id="@Name"
placeholder="@CurrentPlaceholder" autocomplete="@AutoCompleteAttribute" aria-autocomplete="@AriaAutoCompleteAttribute" value="@FormattedValue" @onchange="@OnChange"
onkeypress="Radzen.numericKeyPress(event, @IsInteger().ToString().ToLower(), '@Culture.NumberFormat.NumberDecimalSeparator')"

View File

@@ -303,13 +303,6 @@ namespace Radzen.Blazor
[Parameter]
public bool ReadOnly { get; set; }
/// <summary>
/// Gets or sets a value indicating whether input automatic complete is enabled.
/// </summary>
/// <value><c>true</c> if input automatic complete is enabled; otherwise, <c>false</c>.</value>
[Parameter]
public override bool AutoComplete { get; set; } = false;
/// <summary>
/// Gets or sets a value indicating whether up down buttons are shown.
/// </summary>

View File

@@ -42,6 +42,12 @@ namespace Radzen.Blazor
[Parameter]
public IComparable Max { get; set; }
/// <summary>
/// Specifies if value can be null. If true, a null component value will be accepted.
/// </summary>
[Parameter]
public bool AllowNull { get; set; } = false;
/// <inheritdoc />
protected override bool Validate(IRadzenFormComponent component)
{
@@ -54,7 +60,7 @@ namespace Radzen.Blazor
if (value == null)
{
return false;
return AllowNull;
}
@@ -91,4 +97,4 @@ namespace Radzen.Blazor
}
}
}
}
}

View File

@@ -8,11 +8,11 @@
{
<span class="rz-pager-summary">@((MarkupString)string.Format(PagingSummaryFormat, CurrentPage + 1, numberOfPages, Count))</span>
}
<a d="@(GetId() + "fp")" class="rz-pager-first rz-pager-element @(skip > 0 ? "": "rz-state-disabled") @(focusedIndex == -2 ? "rz-state-focused": "")" @onclick:preventDefault="true" @onclick="@(() => FirstPage())" aria-label="@FirstPageAriaLabel" role="button" title="@FirstPageTitle" disabled="@(CurrentPage <= 0)">
<a d="@(GetId() + "fp")" class="rz-pager-first rz-pager-element @(skip > 0 ? "": "rz-state-disabled") @(focusedIndex == -2 ? "rz-state-focused": "")" @onclick:preventDefault="true" @onclick="@(() => OnFirstPageClick())" aria-label="@FirstPageAriaLabel" role="button" title="@FirstPageTitle" disabled="@(CurrentPage <= 0)">
<span class="rz-pager-icon rzi rzi-step-backward"></span>
</a>
<a id="@(GetId() + "pp")" class="rz-pager-prev rz-pager-element @(skip > 0 ? "": "rz-state-disabled") @(focusedIndex == -1 ? "rz-state-focused": "")" @onclick:preventDefault="true" @onclick="@(() => PrevPage())" aria-label="@PrevPageAriaLabel" role="button" title="@PrevPageTitle" disabled="@(CurrentPage <= 0)">
<a id="@(GetId() + "pp")" class="rz-pager-prev rz-pager-element @(skip > 0 ? "": "rz-state-disabled") @(focusedIndex == -1 ? "rz-state-focused": "")" @onclick:preventDefault="true" @onclick="@(() => OnPrevPageClick())" aria-label="@PrevPageAriaLabel" role="button" title="@PrevPageTitle" disabled="@(CurrentPage <= 0)">
<span class="rz-pager-icon rzi rzi-caret-left"></span>
@if (PrevPageLabel != null)
{
@@ -23,11 +23,11 @@
<span class="rz-pager-pages">
@foreach (var i in Enumerable.Range(startPage, Math.Min(endPage + 1, PageNumbersCount)))
{
<a id="@(GetId() + i.ToString() + "p")" class="rz-pager-page rz-pager-element @(i == CurrentPage ? "rz-state-active" : "") @(startPage + focusedIndex == i ? "rz-state-focused": "")" @onclick:preventDefault="true" @onclick="@(() => GoToPage(i))" aria-current="@(i == CurrentPage ? "page" : null)" aria-label="@string.Format(PageAriaLabelFormat, (i + 1).ToString())" role="button" title="@string.Format(PageTitleFormat, (i + 1).ToString())">@(i + 1)</a>
<a id="@(GetId() + i.ToString() + "p")" class="rz-pager-page rz-pager-element @(i == CurrentPage ? "rz-state-active" : "") @(startPage + focusedIndex == i ? "rz-state-focused": "")" @onclick:preventDefault="true" @onclick="@(() => OnPageClick(i, startPage))" aria-current="@(i == CurrentPage ? "page" : null)" aria-label="@string.Format(PageAriaLabelFormat, (i + 1).ToString())" role="button" title="@string.Format(PageTitleFormat, (i + 1).ToString())">@(i + 1)</a>
}
</span>
<a id="@(GetId() + "np")" class="rz-pager-next rz-pager-element @((CurrentPage != numberOfPages - 1) ? "": "rz-state-disabled") @(focusedIndex == Math.Min(endPage + 1, PageNumbersCount)? "rz-state-focused": "")" @onclick:preventDefault="true" @onclick="@(() => NextPage())" aria-label="@NextPageAriaLabel" role="button" title="@NextPageTitle" disabled="@(CurrentPage >= (numberOfPages - 1))">
<a id="@(GetId() + "np")" class="rz-pager-next rz-pager-element @((CurrentPage != numberOfPages - 1) ? "": "rz-state-disabled") @(focusedIndex == Math.Min(endPage + 1, PageNumbersCount)? "rz-state-focused": "")" @onclick:preventDefault="true" @onclick="@(() => OnNextPageClick(endPage))" aria-label="@NextPageAriaLabel" role="button" title="@NextPageTitle" disabled="@(CurrentPage >= (numberOfPages - 1))">
@if (NextPageLabel != null)
{
<span class="rz-pager-label">@NextPageLabel</span>
@@ -35,7 +35,7 @@
<span class="rz-pager-icon rzi rzi-caret-right"></span>
</a>
<a id="@(GetId() + "lp")" class="rz-pager-last rz-pager-element @((CurrentPage != numberOfPages - 1) ? "": "rz-state-disabled") @(focusedIndex == Math.Min(endPage + 1, PageNumbersCount) + 1 ? "rz-state-focused": "")" @onclick:preventDefault="true" @onclick="@(() => LastPage())" aria-label="@LastPageAriaLabel" role="button" title="@LastPageTitle" disabled="@(CurrentPage >= (numberOfPages - 1))">
<a id="@(GetId() + "lp")" class="rz-pager-last rz-pager-element @((CurrentPage != numberOfPages - 1) ? "": "rz-state-disabled") @(focusedIndex == Math.Min(endPage + 1, PageNumbersCount) + 1 ? "rz-state-focused": "")" @onclick:preventDefault="true" @onclick="@(() => OnLastPageClick(endPage))" aria-label="@LastPageAriaLabel" role="button" title="@LastPageTitle" disabled="@(CurrentPage >= (numberOfPages - 1))">
<span class="rz-pager-icon rzi rzi-step-forward"></span>
</a>

View File

@@ -338,6 +338,60 @@ namespace Radzen.Blazor
}
}
async Task OnFirstPageClick()
{
focusedIndex = -2;
await FirstPage();
if (skip == 0)
{
focusedIndex = focusedIndex + 2;
}
}
async Task OnPrevPageClick()
{
focusedIndex = -1;
await PrevPage();
if (skip == 0)
{
focusedIndex++;
}
}
async Task OnPageClick(int i, int startPage)
{
focusedIndex = i - startPage;
await GoToPage(i);
}
async Task OnNextPageClick(int endPage)
{
focusedIndex = Math.Min(endPage + 1, PageNumbersCount);
await NextPage();
if (CurrentPage == numberOfPages - 1)
{
focusedIndex--;
}
}
async Task OnLastPageClick(int endPage)
{
focusedIndex = Math.Min(endPage + 1, PageNumbersCount) + 1;
await LastPage();
if (CurrentPage == numberOfPages - 1)
{
focusedIndex = focusedIndex - 2;
}
}
internal void SetCurrentPage(int page)
{
if (CurrentPage != page)

View File

@@ -30,10 +30,10 @@ namespace Radzen.Blazor
/// }
/// </code>
/// </example>
public partial class RadzenSeriesAnnotation<TItem> : RadzenChartComponentBase, IChartSeriesOverlay
public partial class RadzenSeriesAnnotation<TItem> : RadzenChartComponentBase, IChartSeriesOverlay, IDisposable
{
/// <summary>
/// The data item from the series this annotation applies to.
/// The data item from the series this annotation applies to.
/// </summary>
[Parameter]
public TItem Data { get; set; }
@@ -126,7 +126,7 @@ namespace Radzen.Blazor
break;
}
return builder =>
return builder =>
{
builder.OpenElement(0, "g");
builder.OpenComponent<Text>(1);
@@ -156,5 +156,8 @@ namespace Radzen.Blazor
{
return null;
}
/// <inheritdoc/>
public void Dispose() => series?.Overlays.Remove(this);
}
}

View File

@@ -1,13 +1,14 @@
@using Radzen.Blazor.Rendering
@inherits RadzenChartComponentBase
@implements IChartSeriesOverlay
@implements IDisposable
@code {
IChartSeries series;
[CascadingParameter]
protected IChartSeries Series
{
protected IChartSeries Series
{
get
{
return series;
@@ -33,7 +34,7 @@
{
builder.AddContent(1,
@<g>
<Text @key="@($"{label.Position}-{Chart.Series.IndexOf(series)}")"
<Text @key="@($"{label.Position}-{Chart.Series.IndexOf(series)}")"
Value="@label.Text" Position="@label.Position" TextAnchor="@label.TextAnchor" class="rz-series-data-label" />
</g>
);
@@ -47,7 +48,7 @@
{
return parameters.DidParameterChange(nameof(Visible), Visible);
}
public bool Contains(double mouseX, double mouseY, int tolerance)
{
return false;
@@ -57,4 +58,6 @@
{
return null;
}
public void Dispose() => series?.Overlays.Remove(this);
}

View File

@@ -1,6 +1,7 @@
@using Radzen.Blazor.Rendering
@inherits RadzenGridLines
@implements IChartSeriesOverlay
@implements IDisposable
@code {
public RadzenSeriesTrendLine()
@@ -76,4 +77,6 @@
{
return null;
}
public void Dispose() => series?.Overlays.Remove(this);
}

View File

@@ -1,6 +1,7 @@
@using Radzen.Blazor.Rendering
@inherits RadzenGridLines
@implements IChartSeriesOverlay
@implements IDisposable
@code {
public RadzenSeriesValueLine()
@@ -122,4 +123,5 @@
builder.CloseComponent();
};
}
public void Dispose() => series?.Overlays.Remove(this);
}

View File

@@ -326,6 +326,35 @@ namespace Radzen.Blazor
SelectedItem?.Unselect();
SelectedItem = null;
}
/// <summary>
/// Forces the specified <paramref name="item"/> or, if
/// <paramref name="item"/> is <c>null</c>, all items in the tree to be
/// re-evaluated such that items lazily created via <see cref="Expand"/>
/// are realised if the underlying data model has been changed from
/// somewhere else.
/// </summary>
/// <param name="item">The item to be reloaded or <c>null</c> to refresh
/// the root nodes of the tree.</param>
/// <returns>A task to wait for the operation to complete.</returns>
public async Task Reload(RadzenTreeItem item = null) {
// Implementation node: I am absolute not sure whether "ExpandItem"
// is the "right" way to to this, but it does exactly what I need.
// The rationale behind the public "Reload" method is that (i) just
// making "ExpandItem" public would create an API that is not
// intuitively named and (ii) if "ExpandItem" gets changed in the
// future such that it cannot be used for this hack anymore, the
// implementation could be swapped with a different one without
// breaking the public API.
if (item == null) {
foreach (var i in this.items) {
await this.ExpandItem(i);
}
} else {
await this.ExpandItem(item);
}
}
internal async Task ExpandItem(RadzenTreeItem item)
{
var args = new TreeExpandEventArgs()

View File

@@ -16,7 +16,7 @@
@for (var date = StartDate; date < EndDate; date = date.AddMinutes(MinutesPerSlot))
{
var slotDate = date;
<div @onclick=@(args => OnSlotClick(slotDate)) @attributes=@Attributes(date) ondragover="event.preventDefault();" @ondrop=@(args => @OnDrop(slotDate))></div>
<div @onclick=@(args => OnSlotClick(slotDate)) ondragover="event.preventDefault();" @ondrop=@(args => @OnDrop(slotDate)) @attributes=@Attributes(date)></div>
}
</div>
</div>

View File

@@ -81,7 +81,7 @@
@for (var day = 0; day < 7; day ++)
{
var dayOfWeek = StartDate.AddDays(days++);
<div @onclick="@(args => OnSlotClick(dayOfWeek))" @attributes=@Attributes(dayOfWeek) ondragover="event.preventDefault();" @ondrop=@(args => @OnDrop(dayOfWeek))>
<div @onclick="@(args => OnSlotClick(dayOfWeek))" ondragover="event.preventDefault();" @ondrop=@(args => @OnDrop(dayOfWeek)) @attributes=@Attributes(dayOfWeek)>
<div class="rz-slot-title @(dayOfWeek == CurrentDate ? " rz-state-focused" : "")">
@dayOfWeek.Day
</div>

View File

@@ -16,20 +16,64 @@
}
}
@mixin rz-utility-list-css($property, $list) {
@mixin rz-utility-list-css($property, $list, $shorthand: 'none', $unit: 'none') {
@each $value in $list {
.rz-#{$property}-#{$value} {
#{$property}: #{$value} !important;
@if $shorthand != none {
.rz-#{$shorthand}-#{$value} {
@if $unit != 'none' {
@if $unit == 'percent' {
#{$property}: #{$value}#{'%'} !important;
} @else {
#{$property}: #{$value}#{$unit} !important;
}
} @else {
#{$property}: #{$value} !important;
}
}
} @else {
.rz-#{$property}-#{$value} {
@if $unit != 'none' {
@if $unit == 'percent' {
#{$property}: #{$value}#{'%'} !important;
} @else {
#{$property}: #{$value}#{$unit} !important;
}
} @else {
#{$property}: #{$value} !important;
}
}
}
}
}
@mixin rz-utility-list-breakpoints-css($property, $list, $breakpoints) {
@mixin rz-utility-list-breakpoints-css($property, $list, $breakpoints, $shorthand: 'none', $unit: 'none') {
@each $breakpoint, $breakpoint-value in $breakpoints {
@media (min-width: #{$breakpoint-value}) {
@each $value in $list {
.rz-#{$property}-#{$breakpoint}-#{$value} {
#{$property}: #{$value} !important;
@if $shorthand != 'none' {
.rz-#{$shorthand}-#{$breakpoint}-#{$value} {
@if $unit != 'none' {
@if $unit == 'percent' {
#{$property}: #{$value}#{'%'} !important;
} @else {
#{$property}: #{$value}#{$unit} !important;
}
} @else {
#{$property}: #{$value} !important;
}
}
} @else {
.rz-#{$property}-#{$breakpoint}-#{$value} {
@if $unit != 'none' {
@if $unit == 'percent' {
#{$property}: #{$value}#{'%'} !important;
} @else {
#{$property}: #{$value}#{$unit} !important;
}
} @else {
#{$property}: #{$value} !important;
}
}
}
}
}

View File

@@ -441,7 +441,54 @@ $justify-content: normal, stretch, center, start, end, flex-start, flex-end, lef
$align-items: normal, stretch, center, start, end, flex-start, flex-end;
@include rz-utility-list-css('align-items', $align-items);
//---- CSS classes
// Overflow
// Example .rz-overflow-auto
$overflow: auto, scroll, visible, hidden;
@include rz-utility-list-css('overflow', $overflow);
// Width Percentage
// Example .rz-w-25
$width: 25, 50, 75, 100;
@include rz-utility-list-css('width', $width, 'w', 'percent');
// Width Viewport
// Example .rz-vw-25
@include rz-utility-list-css('width', $width, 'vw', 'vw');
// Width Keywords
// Example .rz-w-auto
$width-k: auto, fit-content, min-content, max-content, stretch;
@include rz-utility-list-css('width', $width-k, 'w');
// Min-width Percentage
// Example .rz-min-w-25
@include rz-utility-list-css('min-width', $width, 'min-w', 'percent');
// Max-width Percentage
// Example .rz-max-w-25
@include rz-utility-list-css('max-width', $width, 'max-w', 'percent');
// Height Percentage
// Example .rz-h-25
$height: 25, 50, 75, 100;
@include rz-utility-list-css('height', $height, 'h', 'percent');
// Height Viewport
// Example .rz-vh-25
@include rz-utility-list-css('height', $height, 'vh', 'vh');
// Height Keywords
// Example .rz-h-auto
$height-k: auto;
@include rz-utility-list-css('height', $height-k, 'h');
// Min-height Percentage
// Example .rz-min-h-25
@include rz-utility-list-css('min-height', $height, 'min-h', 'percent');
// Max-height Percentage
// Example .rz-max-h-25
@include rz-utility-list-css('max-height', $height, 'max-h', 'percent');
// Color
// Example .rz-color-primary
@@ -451,20 +498,52 @@ $align-items: normal, stretch, center, start, end, flex-start, flex-end;
// Example .rz-background-color-primary
@include rz-color-css('background-color', $rz-theme-colors-map);
// Border Color
// Example .rz-border-color-primary
@include rz-color-css('border-color', $rz-theme-colors-map);
// Border base
// Example .rz-border-start
$border: border, border-start, border-end, border-left, border-right, border-top, border-bottom;
@each $value in $border {
.rz-#{$value} {
border-width: 0;
@if $value == 'border-start' {
border-inline-start-width: var(--rz-border-width);
}
@else if $value == 'border-end' {
border-inline-end-width: var(--rz-border-width);
}
@else {
#{$value}-width: var(--rz-border-width);
}
border-style: solid;
border-color: var(--rz-base);
}
// Border
.rz-#{$value}-0 {
@if $value == 'border-start' {
border-inline-start-width: 0 !important;
}
@else if $value == 'border-end' {
border-inline-end-width: 0 !important;
}
@else {
#{$value}-width: 0 !important;
}
}
}
// Border with color
// Example .rz-border-primary
@each $color, $value in $rz-theme-colors-map {
.rz-border-#{$color} {
border-width: var(--rz-border-width);
border-style: solid;
border-color: var(--rz-#{$color}) !important;
border-color: var(--rz-#{$color}) !important;
}
}
// Border Color
// Example .rz-border-color-primary. Use in combination with .rz-border base classes.
@include rz-color-css('border-color', $rz-theme-colors-map);
// Ripple
.rz-ripple {
@include rz-ripple($pseudo: true);

View File

@@ -349,10 +349,11 @@ window.Radzen = {
if (!el || !ref) return;
var hidden = el.querySelector('input[type="hidden"]');
var inputs = [...el.querySelectorAll('.rz-security-code-input')];
Radzen[id] = {};
Radzen[id].inputs = [...el.querySelectorAll('.rz-security-code-input')];
Radzen[id].paste = function (e) {
if (e.clipboardData) {
var value = e.clipboardData.getData('text');
@@ -362,15 +363,15 @@ window.Radzen = {
if (isNumber && isNaN(+value[i])) {
continue;
}
inputs[i].value = value[i];
Radzen[id].inputs[i].value = value[i];
}
var code = inputs.map(i => i.value).join('').trim();
var code = Radzen[id].inputs.map(i => i.value).join('').trim();
hidden.value = code;
ref.invokeMethodAsync('RadzenSecurityCode.OnValueChange', code);
inputs[inputs.length - 1].focus();
Radzen[id].inputs[Radzen[id].inputs.length - 1].focus();
}
e.preventDefault();
@@ -400,14 +401,14 @@ window.Radzen = {
e.currentTarget.value = ch;
var value = inputs.map(i => i.value).join('').trim();
var value = Radzen[id].inputs.map(i => i.value).join('').trim();
hidden.value = value;
ref.invokeMethodAsync('RadzenSecurityCode.OnValueChange', value);
var index = inputs.indexOf(e.currentTarget);
if (index < inputs.length - 1) {
inputs[index + 1].focus();
var index = Radzen[id].inputs.indexOf(e.currentTarget);
if (index < Radzen[id].inputs.length - 1) {
Radzen[id].inputs[index + 1].focus();
}
}
@@ -416,22 +417,22 @@ window.Radzen = {
if (keyCode == 8) {
e.currentTarget.value = '';
var value = inputs.map(i => i.value).join('').trim();
var value = Radzen[id].inputs.map(i => i.value).join('').trim();
hidden.value = value;
ref.invokeMethodAsync('RadzenSecurityCode.OnValueChange', value);
var index = inputs.indexOf(e.currentTarget);
var index = Radzen[id].inputs.indexOf(e.currentTarget);
if (index > 0) {
inputs[index - 1].focus();
Radzen[id].inputs[index - 1].focus();
}
}
}
for (var i = 0; i < inputs.length; i++) {
inputs[i].addEventListener(navigator.userAgent.match(/Android/i) ? 'textInput' : 'keypress', Radzen[id].keyPress);
inputs[i].addEventListener(navigator.userAgent.match(/Android/i) ? 'textInput' : 'keydown', Radzen[id].keyDown);
inputs[i].addEventListener('paste', Radzen[id].paste);
for (var i = 0; i < Radzen[id].inputs.length; i++) {
Radzen[id].inputs[i].addEventListener(navigator.userAgent.match(/Android/i) ? 'textInput' : 'keypress', Radzen[id].keyPress);
Radzen[id].inputs[i].addEventListener(navigator.userAgent.match(/Android/i) ? 'textInput' : 'keydown', Radzen[id].keyDown);
Radzen[id].inputs[i].addEventListener('paste', Radzen[id].paste);
}
},
createSlider: function (
@@ -490,7 +491,7 @@ window.Radzen = {
? e.targetTouches[0].pageX - e.target.getBoundingClientRect().left
: e.offsetX;
var percent = offsetX / parent.offsetWidth;
var newValue = percent * max;
var newValue = percent * (max - min) + min;
var oldValue = range ? value[slider.isMin ? 0 : 1] : value;
if (newValue >= min && newValue <= max && newValue != oldValue) {
slider.invokeMethodAsync(
@@ -938,10 +939,13 @@ window.Radzen = {
return;
}
if (e.code === 'NumpadDecimal') {
e.target.value += decimalSeparator;
e.preventDefault();
return;
if (e.code === 'NumpadDecimal') {
var cursorPosition = e.target.selectionEnd;
e.target.value = [e.target.value.slice(0, e.target.selectionStart), decimalSeparator, e.target.value.slice(e.target.selectionEnd)].join('');
e.target.selectionStart = ++cursorPosition;
e.target.selectionEnd = cursorPosition;
e.preventDefault();
return;
}
var ch = String.fromCharCode(e.charCode);
@@ -1393,6 +1397,7 @@ window.Radzen = {
var lastDialog = dialogs[dialogs.length - 1];
if (lastDialog) {
lastDialog.options = options;
lastDialog.removeEventListener('keydown', Radzen.focusTrap);
lastDialog.addEventListener('keydown', Radzen.focusTrap);
@@ -1524,15 +1529,20 @@ window.Radzen = {
}
}
Radzen.dialogService.invokeMethodAsync('DialogService.Close', null);
var dialogs = document.querySelectorAll('.rz-dialog-content');
if (dialogs.length <= 1) {
document.removeEventListener('keydown', Radzen.closePopupOrDialog);
delete Radzen.dialogService;
var layout = document.querySelector('.rz-layout');
if (layout) {
layout.removeEventListener('keydown', Radzen.disableKeydown);
if (dialogs.length == 0) return;
var lastDialog = dialogs[dialogs.length - 1];
if (lastDialog && lastDialog.options && lastDialog.options.closeDialogOnEsc) {
Radzen.dialogService.invokeMethodAsync('DialogService.Close', null);
if (dialogs.length <= 1) {
document.removeEventListener('keydown', Radzen.closePopupOrDialog);
delete Radzen.dialogService;
var layout = document.querySelector('.rz-layout');
if (layout) {
layout.removeEventListener('keydown', Radzen.disableKeydown);
}
}
}
}
@@ -1836,8 +1846,22 @@ window.Radzen = {
};
ref.clickListener = function (e) {
if (e.target && e.target.matches('a,button')) {
e.preventDefault();
if (e.target) {
if (e.target.matches('a,button')) {
e.preventDefault();
}
for (var img of ref.querySelectorAll('img.rz-state-selected')) {
img.classList.remove('rz-state-selected');
}
if (e.target.matches('img')) {
e.target.classList.add('rz-state-selected');
var range = document.createRange();
range.selectNode(e.target);
getSelection().removeAllRanges();
getSelection().addRange(range);
}
}
}
@@ -1871,6 +1895,7 @@ window.Radzen = {
} else {
document.execCommand("insertHTML", false, '<img src="' + result.url + '">');
}
instance.invokeMethodAsync('OnUploadComplete', xhr.responseText);
} else {
instance.invokeMethodAsync('OnError', xhr.responseText);
}
@@ -1940,7 +1965,8 @@ window.Radzen = {
var selection = getSelection();
var range = selection.rangeCount > 0 && selection.getRangeAt(0);
var parent = range && range.commonAncestorContainer;
var inside = false;
var img = container.querySelector('img.rz-state-selected');
var inside = img && selector == 'img';
while (parent) {
if (parent == container) {
inside = true;
@@ -1953,7 +1979,10 @@ window.Radzen = {
}
var target = selection.focusNode;
var innerHTML;
if (target) {
if (img && selector == 'img') {
target = img;
} else if (target) {
if (target.nodeType == 3) {
target = target.parentElement;
} else {
@@ -1966,9 +1995,10 @@ window.Radzen = {
target = target.closest(selector);
}
}
return attributes.reduce(function (result, name) {
if (target) {
result[name] = target[name].toString();
result[name] = name == 'innerText' ? target[name] : target.getAttribute(name);
}
return result;
}, { innerText: selection.toString(), innerHTML: innerHTML });

View File

@@ -20,9 +20,6 @@
"content": [
{
"files": ["api/**.yml", "api/index.md"]
},
{
"files": ["guides/**.md", "guides/**/toc.yml", "toc.yml", "*.md"]
}
],
"resource": [

View File

@@ -1,64 +0,0 @@
# Accordion component
This article demonstrates how to use the Accordion component.
## Single item expand
```
<RadzenAccordion>
<Items>
<RadzenAccordionItem Text="Orders" Icon="account_balance_wallet">
Details for Orders
</RadzenAccordionItem>
<RadzenAccordionItem Text="Employees" Icon="account_box">
Details for Employees
</RadzenAccordionItem>
<RadzenAccordionItem Text="Customers" Icon="accessibility">
Details for Customers
</RadzenAccordionItem>
</Items>
</RadzenAccordion>
```
## Multiple items expand
```
<RadzenAccordion Multiple="true">
<Items>
<RadzenAccordionItem Text="Orders" Icon="account_balance_wallet">
Details for Orders
</RadzenAccordionItem>
<RadzenAccordionItem Text="Employees" Icon="account_box">
Details for Employees
</RadzenAccordionItem>
<RadzenAccordionItem Text="Customers" Icon="accessibility">
Details for Customers
</RadzenAccordionItem>
</Items>
</RadzenAccordion>
```
## Expand/Collapse events
```
<RadzenAccordion Collapse=@(args => Change(args, "collapsed"))
Expand=@(args => Change(args, "expanded"))>
<Items>
<RadzenAccordionItem Text="Orders" Icon="account_balance_wallet">
Details for Orders
</RadzenAccordionItem>
<RadzenAccordionItem Text="Employees" Icon="account_box">
Details for Employees
</RadzenAccordionItem>
<RadzenAccordionItem Text="Customers" Icon="accessibility">
Details for Customers
</RadzenAccordionItem>
</Items>
</RadzenAccordion>
@code {
void Change(object value, string action)
{
Console.WriteLine($"Item with index {value} {action}");
}
}
```

View File

@@ -1,131 +0,0 @@
# ArcGauge component
This article demonstrates how to use RadzenArcGauge.
## Basic usage
Here is basic example that creates an arc gauge with minimal configuration.
```
<RadzenArcGauge Style="width: 300px; height: 300px">
<RadzenArcGaugeScale>
<RadzenArcGaugeScaleValue Value="50" />
</RadzenArcGaugeScale>
</RadzenArcGauge>
```
RadzenArcGaugeScale tag is used to add a scale and configure its options - min and max value, start and end angle, tick display etc.
RadzenArcGaugeScaleValue tag adds and configures a value of the ArcGaugeScale it is a child of.
Radzen Blazor gauges can have multiple scales and every scale can have multiple pointers or values.
## Scale configuration
### Min, max and step
By default the `Min` property of both scale types (Arc and Arc) is set to `0`. `Max` is set to `100` and `Step` is set to `20`.
To override the defaults use the `Min`, `Max` and `Step` properties of the `RadzenArcGaugeScale` tag.
```
<RadzenArcGauge Style="width: 300px; height: 300px">
<RadzenArcGaugeScale Min="100" Max="1000" Step="100">
<RadzenArcGaugeScaleValue Value="50" />
</RadzenArcGaugeScale>
</RadzenArcGauge>
```
### Tick configuration
By default the RadzenArcGaugeScale does not display ticks. You need to set the `TickPosition` property to `GaugeTickPosition.Outside` or `GaugeTickPosition.Inside`. To hide the ticks altogether use `GaugeTickPosition.None`.
```
<RadzenArcGauge Style="width: 300px; height: 300px">
<RadzenArcGaugeScale TickPosition="GaugeTickPosition.Outside">
<RadzenArcGaugeScaleValue Value="50" />
</RadzenArcGaugeScale>
</RadzenArcGauge>
```
Minor ticks are not displayed by default. To display them set the MinorStep property to a value greater than `0`.
```
<RadzenArcGauge Style="width: 300px; height: 300px">
<RadzenArcGaugeScale TickPosition="GaugeTickPosition.Outside" MinorStep="5">
<RadzenArcGaugeScaleValue Value="50" />
</RadzenArcGaugeScale>
</RadzenArcGauge>
```
### Change the start and and angles
By default the `StartAngle` property of the gauge scales is set to `-90` and `EndAngle` is set to `90`. This makes
the default shape half a circle. Here is how to create a gauge which is a full circle:
```
<RadzenArcGauge>
<RadzenArcGaugeScale StartAngle="0" EndAngle="360">
<RadzenArcGaugeScaleValue Value="50" />
</RadzenArcGaugeScale>
</RadzenArcGauge>
```
### Format the values
The scale ticks labels displays values with default formatting (`ToString()`). This can be customized in two ways - via the `FormatString` or the `Formatter` properties.
`FormatString` supports the [standard .NET Number formats](https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings).
```
<RadzenArcGauge Style="width: 300px; height: 300px">
<RadzenArcGaugeScale FormatString="{0:C}">
<RadzenArcGaugeScaleValue Value="50" />
</RadzenGaugeGaugeScale>
</RadzenGaugeGauge>
```
```
<RadzenArcGauge Style="width: 300px; height: 300px">
<RadzenArcGaugeScale Formatter=@(value => value.ToString())>
<RadzenArcGaugeScaleValue Value="50" />
</RadzenGaugeGaugeScale>
</RadzenGaugeGauge>
```
### Change the scale position
You can use the `X` and `Y` property of the scales to change the position of their center. Both properties have a default value of `0.5` which means
that by default the center of a scale is the middle of the gauge. `X` and `Y` are a multiplier of the width and height.
For example you can move the center of the scale to the bottom of the component by setting `Y` to `1`.
```
<RadzenArcGauge Style="width: 300px; height: 300px">
<RadzenArcGaugeScale Y="1">
<RadzenArcGaugeScaleValue Value="50" />
</RadzenGaugeGaugeScale>
</RadzenGaugeGauge>
```
Using `X` and `Y` is also useful when you have multiple scales - this allows you to prevent them from overlapping which they will do by default.
### Change the scale radius
By default the radius is set to be half the size of the Gauge - the smaller of its pixel width or height. You can tweak that
by setting the `Radius` property. It is also a multiplier - the value you specify is multiplied by the initial value (half the width or height depending on which is smaller).
The reason Radius is a multiplier and not an absolute value is responsiveness - users of smaller devices would expect to see a scale which is proportionally the same.
Here is how to make a scale twice as small
```
<RadzenArcGauge Style="width: 300px; height: 300px">
<RadzenArcGaugeScale Radius="0.5">
<RadzenArcGaugeScaleValue Value="50" />
</RadzenGaugeGaugeScale>
</RadzenGaugeGauge>
```
## Value configuration
### Hide the value
By default the `Value` property is displayed below the scale. You can hide it by setting the `ShowValue` property to `false`.
```
<RadzenArcGauge>
<RadzenArcGaugeScale>
<RadzenArcGaugeScaleValue Value="50" ShowValue="false" />
</RadzenArcGaugeScale>
</RadzenArcGauge>
```
### Customize the value display
Use the `Template` property of the pointer to tweak the default value appearance.
```
<RadzenArcGauge>
<RadzenArcGaugeScale Min="0" Max="260">
<RadzenArcGaugeScaleValue Value=@value>
<Template Context="value">
<h4>
@value.Value <sup>km/h</sup>
</h4>
</Template>
</RadzenArcGaugeScaleValue>
</RadzenArcGaugeScale>
</RadzenArcGauge>
```

View File

@@ -1,58 +0,0 @@
# AutoComplete component
This article demonstrates how to use the AutoComplete component.
## Data-binding
To display data in AutoComplete component you need to set collection of items (`IEnumerable<>`) to `Data` property and `TextProperty` to the string property name of the item in the collection.
### Populate data when initialized
```
<RadzenAutoComplete Data="@customers" TextProperty="CompanyName" Change="@Changed" />
@code {
IEnumerable<Customer> customers;
protected override void OnInitialized()
{
customers = dbContext.Customers.ToList();
}
void OnChange(object value)
{
Console.WriteLine($"Value changed to {value}");
}
}
```
### Populate data on demand using LoadData event.
```
<RadzenAutoComplete Data="@customers" TextProperty="CompanyName" Change="@Changed" LoadData=@OnLoadData />
@code {
IEnumerable<Customer> customers;
void OnChange(object value)
{
Console.WriteLine($"Value changed to {value}");
}
void OnLoadData(LoadDataArgs args)
{
Console.WriteLine($"LoadData with filter: {args.Filter}");
customers = dbContext.Customers.Where(c => c.CustomerID.Contains(args.Filter) || c.ContactName.Contains(args.Filter)).ToList();
InvokeAsync(StateHasChanged);
}
}
```
## Get and set the value
As all Radzen Blazor input components the AutoComplete has a `Value` property which gets and sets the value of the component.
Use `@bind-Value` to get the user input.
```
<RadzenAutoComplete @bind-Value=@value />
@code {
string value = "SomeValue";
}
```

View File

@@ -1,44 +0,0 @@
# Badge component
This article demonstrates how to use the Badge component.
## Badge Style
```
<RadzenBadge BadgeStyle="BadgeStyle.Primary" Text="Primary" />
<RadzenBadge BadgeStyle="BadgeStyle.Secondary" Text="Secondary" />
<RadzenBadge BadgeStyle="BadgeStyle.Light" Text="Light" />
<RadzenBadge BadgeStyle="BadgeStyle.Success" Text="Success" />
<RadzenBadge BadgeStyle="BadgeStyle.Danger" Text="Danger" />
<RadzenBadge BadgeStyle="BadgeStyle.Warning" Text="Warning" />
<RadzenBadge BadgeStyle="BadgeStyle.Info" Text="Info" />
```
## Pills
```
<RadzenBadge BadgeStyle="BadgeStyle.Primary" IsPill="true" Text="Primary" />
<RadzenBadge BadgeStyle="BadgeStyle.Secondary" IsPill="true" Text="Secondary" />
<RadzenBadge BadgeStyle="BadgeStyle.Light" IsPill="true" Text="Light" />
<RadzenBadge BadgeStyle="BadgeStyle.Success" IsPill="true" Text="Success" />
<RadzenBadge BadgeStyle="BadgeStyle.Danger" IsPill="true" Text="Danger" />
<RadzenBadge BadgeStyle="BadgeStyle.Warning" IsPill="true" Text="Warning" />
<RadzenBadge BadgeStyle="BadgeStyle.Info" IsPill="true" Text="Info" />
```
## In Button
```
<RadzenButton ButtonStyle="ButtonStyle.Info">
Button
<RadzenBadge BadgeStyle="BadgeStyle.Primary" Text="15" />
</RadzenButton>
<RadzenButton ButtonStyle="ButtonStyle.Light">
Button
<RadzenBadge BadgeStyle="BadgeStyle.Primary" IsPill="@true" Text="15" />
</RadzenButton>
```
## Define custom content
```
<RadzenBadge BadgeStyle="BadgeStyle.Primary">
Childcontent
</RadzenBadge>
```

View File

@@ -1,30 +0,0 @@
# Badge component
This article demonstrates how to use the BreadCrumb component.
The Bread Crumb offers a Menu like experience, with an optional custom Template.
## Standard Bread Crumb Menu
```
<RadzenBreadCrumb>
<Items>
<RadzenBreadCrumbItem Text="Layout & Navigation" />
<RadzenBreadCrumbItem Text="Bread Crumb" />
</Items>
</RadzenBreadCrumb>
```
## Optional Template
The optional Template can be defined using the `Template` Property of the `RadzenBreadCrumb` component.
The Context ist of Type `RadzenBreadCrumbItem`.
```
<RadzenBreadCrumb>
<Template context="itm">
<RadzenBadge Text="@itm.Text" />
</Template>
<Items>
<RadzenBreadCrumbItem Text="Layout & Navigation" />
<RadzenBreadCrumbItem Text="Bread Crumb" />
</Items>
</RadzenBreadCrumb>
```
This template renders all items of the Menu in a `RadzenBadge`.

View File

@@ -1,95 +0,0 @@
# Button component
This article demonstrates how to use RadzenButton.
## Basic usage
The most basic configuration of RadzenButton is to set its `Text` property and handle the `Click` event.
```
<RadzenButton Click=@OnSave Text="Save" />
@code {
void OnSave()
{
// Implementation
}
}
```
## Button types
RadzenButton can also submit or reset forms. Use the `ButtonType` property for that.
# [Submit Button](#tab/submit)
```
<RadzenButton ButtonType="ButtonType.Submit" />
```
# [Reset Button](#tab/reset)
```
<RadzenButton ButtonType="ButtonType.Reset" />
```
***
## Appearance
By default RadzenButton renders as a regular button with text. You can change the appearance in various ways.
### Icons and images
You can specify an icon or a custom image which RadzenButton will display before the text.
#### [Icon](#tab/icon)
```
<RadzenButton Icon="account_circle" />
```
#### [Image](#tab/image)
```
<RadzenButton Image="images/save.png" />
```
***
### Custom content
RadzenButton can also have entirely custom child content.
```
<RadzenButton>
Some text
<RadzenImage Path="images/radzen-nuget.png" Style="width:20px;margin-left: 10px;" />
</RadzenButton>
```
### Styles
RadzenButton comes with a predefined set of styles (background and text colors):
#### [Primary](#tab/primary)
```
<RadzenButton ButtonStyle="ButtonStyle.Primary" />
```
#### [Secondary](#tab/secondary)
```
<RadzenButton ButtonStyle="ButtonStyle.Secondary" />
```
#### [Light](#tab/light)
```
<RadzenButton ButtonStyle="ButtonStyle.Light" />
```
#### [Success](#tab/success)
```
<RadzenButton ButtonStyle="ButtonStyle.Success" />
```
#### [Danger](#tab/danger)
```
<RadzenButton ButtonStyle="ButtonStyle.Danger" />
```
#### [Warning](#tab/warning)
```
<RadzenButton ButtonStyle="ButtonStyle.Warning" />
```
#### [Info](#tab/info)
```
<RadzenButton ButtonStyle="ButtonStyle.Info" />
```
***
## Busy indicator
A common usage scanrio is to display busy (or loading) icon to show that a task is running. RadzenButton supports it out of the box
via the `IsBusy` property. Setting it to `true` displays the loading icon.
```
<RadzenButton IsBusy=@busy Click=@OnBusyClick Text="Save" />
@code {
bool busy;
async Task OnBusyClick()
{
busy = true;
// Use await and Task.Delay to yield execution to Blazor and refresh the UI
await Task.Delay(2000);
// Set the busy flag to false after the long task is done
busy = false;
}
}
```

View File

@@ -1,17 +0,0 @@
# Card component
This article demonstrates how to use the Card component.
```
<RadzenCard class="rz-m-3">
<h3 class="h5">Contact</h3>
<RadzenStack Orientation="Orientation.Horizontal">
<RadzenImage Path="@order.Employee?.Photo" Class="rounded-circle float-left rz-mr-4" Style="width: 100px; height: 100px;" />
<div>
<div>Employee</div>
<b>@(order.Employee?.FirstName + " " + order.Employee?.LastName)</b>
<div class="rz-mt-4">Company</div>
<b>@order.Customer?.CompanyName</b>
</div>
</RadzenStack>
</RadzenCard>
```

View File

@@ -1,141 +0,0 @@
# Chart component
This article demonstrates how to use RadzenBlazorChart.
## Series
The chart can display data as bar, column, line, area, pie and donut series. The chart series needs
data and configuration to tell it which property of the data item is the value of the series (Y axis) and which is the category (X axis).
All series have the following common properties:
- Data - specifies the data source which the series should display.
- ValueProperty - the name of the property which provides values for the Y axis of the chart. The property should be of numeric type:
`int`, `long`, `float`, `double`, `decimal`.
- CategoryProperty - the name of the property which provides value for the X axis of the chart. The property can be `string`, `Date` or numeric. If not set RadzenChart will use the index of the data item as its X axis value.
## Basic usage
Here is a very basic example that creates a column chart with minimal configuration.
```
<RadzenChart>
<RadzenColumnSeries Data="@revenue" CategoryProperty="Quarter" ValueProperty="Revenue" />
</RadzenChart>
@code {
class DataItem
{
public string Quarter { get; set; }
public double Revenue { get; set; }
}
DataItem[] revenue = new DataItem[]
{
new DataItem { Quarter = "Q1", Revenue = 234000 },
new DataItem { Quarter = "Q2", Revenue = 284000 },
new DataItem { Quarter = "Q3", Revenue = 274000 },
new DataItem { Quarter = "Q4", Revenue = 294000 }
};
}
```
The `RadzenColumnSeries` tag is used to specify that the chart has a column series. The `Data` property specifies the
data source. The chart will render a column for every `DataItem` instance from the `revenue` array. The Y (value) axis displays
the `Revenue` property and the X (category) axis displays the `Quarter` property.
## Axis configuration
### Min, max and step
By default the Radzen Blazor Chart determines the Y axis minimum and maximum based on the range of values. For example it finds the minimum and maximum values and
uses the closes "nice" number. A nice number is usually a multiple of a power of 10: 0, 10, 100, 1000, 200000 etc.
In the previous example the chart automatically uses 200000 as the minimum and 300000 as the maximum.
To override the defaults use the `Min`, `Max` and `Step` properties of the `RadzenValueAxis` tag.
```
<RadzenChart>
<RadzenColumnSeries Data="@revenue" CategoryProperty="Quarter" ValueProperty="Revenue" />
<RadzenValueAxis Min="0" Max="400000" Step="100000" />
</RadzenChart>
```
### Format axis values
The value axis displays values with default formatting (`ToString()`). This can be customized in two ways - via the `FormatString` or the `Formatter` properties. `FormatString` supports the [standard .NET Number formats](https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings).
```
<RadzenChart>
<RadzenColumnSeries Data="@revenue" CategoryProperty="Quarter" ValueProperty="Revenue" />
<RadzenValueAxis FormatString="{0:C}"/>
</RadzenChart>
```
### Display grid lines
You can make the chart display grid lines for either the value or category axis.
Add a `RadzenGridLines` tag inside `RadzenValueAxis` or `RadzenCategoryAxis` and set its `Visible` property to `true`.
```
<RadzenChart>
<RadzenColumnSeries Data="@revenue" CategoryProperty="Quarter" ValueProperty="Revenue" />
<RadzenValueAxis>
<RadzenGridLines Visible="true" />
</RadzenValueAxis>
<RadzenCategoryAxis>
<RadzenGridLines Visible="true" />
</RadzenCategoryAxis>
</RadzenChart>
```
### Set axis title
Use the `RadzenAxisTitle` tag to display text below the category axis or next to the value axis.
```
<RadzenChart>
<RadzenColumnSeries Data="@revenue" CategoryProperty="Quarter" ValueProperty="Revenue" />
<RadzenValueAxis>
<RadzenAxisTitle Text="Revenue" />
</RadzenValueAxis>
<RadzenCategoryAxis>
<RadzenAxisTitle Text="Quarter" />
</RadzenCategoryAxis>
</RadzenChart>
```
## Legend configuration
The Radzen Blazor Chart displays a legend by default. It uses the `Title` property of the series (or category values for pie series) as items in the legend.
The legend is at the right side of the chart by default. You can change the position of the legend via the `Position` property.
### Legend position
```
<RadzenChart>
<RadzenColumnSeries Data="@revenue" CategoryProperty="Quarter" ValueProperty="Revenue" />
<RadzenLegend Position="LegendPosition.Bottom" />
</RadzenChart>
```
### Hide the legend
To hide the legend set the `Visible` property to `false`.
```
<RadzenChart>
<RadzenColumnSeries Data="@revenue" CategoryProperty="Quarter" ValueProperty="Revenue" />
<RadzenLegend Visible="false" />
</RadzenChart>
```
## Tooltip
The Radzen Blazor chart displays a tooltip when the user hovers series with the mouse. The tooltip by default inclused the series category, value and series name.
### Customize tooltip content
To customize the tooltip content use the `TooltipTemplate` setting of the series.
```
<RadzenChart>
<RadzenColumnSeries Data="@revenue" CategoryProperty="Quarter" ValueProperty="Revenue">
<TooltipTemplate Context="data">
<div>
Revenue for <span>@data.Quarter</span> 2020:
<strong>@data.Revenue</strong>
</div>
</TooltipTemplate>
</RadzenColumnSeries>
</RadzenChart>
```
### Disable tooltips
To disable the tooltips set the `Visible` property of the `RadzenChartTooltipOptions` tag to `false`.
```
<RadzenChart>
<RadzenColumnSeries Data="@revenue" CategoryProperty="Quarter" ValueProperty="Revenue" />
<RadzenChartTooltipOptions Visible="false" />
</RadzenChart>
```

View File

@@ -1,18 +0,0 @@
# CheckBox component
This article demonstrates how to use the CheckBox component.
## Get and set the value
As all Radzen Blazor input components the CheckBox has a `Value` property which gets and sets the value of the component.
Use `@bind-Value` to get the user input.
```
<RadzenCheckBox @bind-Value=@checkBoxValue TriState="true" TValue="bool?" Change=@OnChange />
@code {
bool? checkBoxValue;
void OnChange(bool? value)
{
Console.WriteLine($"Value changed to {value}");
}
}
```

View File

@@ -1,69 +0,0 @@
# CheckBoxList component
This article demonstrates how to use the CheckBoxList component.
## Get and set the value
As all Radzen Blazor input components the CheckBoxList has a `Value` property which gets and sets the value of the component.
Use `@bind-Value` to get the user input. The `TValue` property should be set to the `Value` property type.
## Data-binding
To display data in CheckBoxList component you can statically declare items in the markup and/or set collection of items (`IEnumerable<>`) to `Data` property, `TextProperty` to the string property name of the item in the collection and `ValueProperty` to the property name with unique values in the collection.
### Statically declared items
```
<RadzenCheckBoxList @bind-Value=@values TValue="int" Change=@OnChange>
<Items>
<RadzenCheckBoxListItem Text="Orders" Value="1" />
<RadzenCheckBoxListItem Text="Employees" Value="2" />
<RadzenCheckBoxListItem Text="Customers" Value="3" />
</Items>
</RadzenCheckBoxList>
@code {
IEnumerable<int> values = new int[] { 1 };
void OnChange(IEnumerable<int> value)
{
Console.WriteLine($"Value changed to {string.Join(", ", value)}");
}
}
```
### Items populated from data
```
<RadzenCheckBoxList Data="@data" TextProperty="Name" ValueProperty="Id" @bind-Value=@values TValue="int" Change=@OnChange />
@code {
IEnumerable<int> values = new int[] { 1 };
IEnumerable<MyObject> data = new MyObject[] {
new MyObject(){ Id = 1 , Name = "Orders"}, new MyObject() { Id = 2 , Name = "Employees"}, new MyObject() { Id = 3 , Name = "Customers" } };
void OnChange(IEnumerable<int> value)
{
Console.WriteLine($"Value changed to {string.Join(", ", value)}");
}
}
```
### Statically declared and populated from data items
```
<RadzenCheckBoxList Data="@data" TextProperty="Name" ValueProperty="Id" @bind-Value=@values TValue="int" Change=@OnChange>
<Items>
<RadzenCheckBoxListItem Text="Static item" Value="0" />
</Items>
</RadzenCheckBoxList>
@code {
IEnumerable<int> values = new int[] { 1 };
IEnumerable<MyObject> data = new MyObject[] {
new MyObject(){ Id = 1 , Name = "Orders"}, new MyObject() { Id = 2 , Name = "Employees"}, new MyObject() { Id = 3 , Name = "Customers" } };
void OnChange(IEnumerable<int> value)
{
Console.WriteLine($"Value changed to {string.Join(", ", value)}");
}
}
```
### Orientation
Use Orientation property to set if CheckBoxList orientation is horizontal or vertical.
```
<RadzenCheckBoxList Orientation="Orientation.Vertical" ...
```

View File

@@ -1,18 +0,0 @@
# ColorPicker component
This article demonstrates how to use the ColorPicker component.
## Get and set the value
As all Radzen Blazor input components the ColorPicker has a `Value` property which gets and sets the value of the component.
Use `@bind-Value` to get the user input.
```
<RadzenColorPicker @bind-Value=@color Change=@OnChange />
@code {
string color = "rgb(68, 58, 110)";
void OnChange(string value)
{
Console.WriteLine($"Value changed to {value}");
}
}
```

View File

@@ -1,65 +0,0 @@
# CompareValidator component
This article demonstrates how to use RadzenCompareValidator.
## Basic usage
RadzenCompareValidator compares the user input agains a predefined value or another component.
To use it perform these steps:
1. Add an input component and set its `Name`. Data-bind its value to a model property via `@bind-Value=@model.Property`.
1. Add RadzenCompareValidator and set its `Component` property to the `Name` of the input component. Set its `Value` property to
the value you want to compare with (usually another model property).
> [!IMPORTANT]
> RadzenCompareValidator works only inside [RadzenTemplateForm](templateform.md).
Here is a typical user registration form which checks if the user entered the same password.
```
<RadzenTemplateForm TItem="Registration" Data=@model>
<p>
<RadzenLabel Text="Password" />
<RadzenPassword Name="Password" @bind-Value=@model.Password />
<RadzenRequiredValidator Component="Password" Text="Enter password" />
</p>
<p>
<RadzenLabel Text="Repeat Password" />
<RadzenPassword Name="RepeatPassword" @bind-Value=@model.RepeatPassword />
<RadzenRequiredValidator Component="RepeatPassword" Text="Repeat your password" />
<RadzenCompareValidator Visible=@(!string.IsNullOrEmpty(model.RepeatPassword)) Value=@model.Password Component="RepeatPassword" Text="Passwords should be the same" Popup=@popup Style="position: absolute" />
</p>
<RadzenButton ButtonType="ButtonType.Submit" Text="Submit"></RadzenButton>
</RadzenTemplateForm>
@code {
class Registration
{
public string Password { get; set; }
public string RepeatPassword { get; set; }
}
Registration model = new Registration();
}
```
## Conditional validation
To make the validator conditional you can set its `Visible` property. When set to `false` the validator will not run.
In this example `Visible` is set to `!string.IsNullOrEmpty(model.RepeatPassword)` - the validator will not run if `RepeatPassword` is empty.
```
<RadzenCompareValidator Visible=@(!string.IsNullOrEmpty(model.RepeatPassword)) Value=@model.Password Component="RepeatPassword" Text="Passwords should be the same" Popup=@popup Style="position: absolute" />
```
## Comparison operator
By default RadzenCompareValidator checks if the component value is equal to `Value`. This can be changed via the `Operator` property.
```
<RadzenNumeric Name="Count" @bind-Value=@model.Count />
<RadzenCompareValidator Component="Count" Text="Count should be less than 10" Operator="CompareOperator.LessThan" Value="10" />
```
## Appearance
By default RadzenCompareValidator appears next to the component it validates.
To make it appear below set its `Style` to `"display:block"`.
```
<RadzenNumeric Name="Count" @bind-Value=@model.Count />
<RadzenCompareValidator Style="display:block" Component="Count" Text="Count should be less than 10" Operator="CompareOperator.LessThan" Value="10" />
```
To make it appear as a styled popup set its `Popup` property to `true` and set its CSS position to `absolute`. The validated component should have `display: block` so the validation message appears right below it.
```
<RadzenNumeric Name="Count" @bind-Value=@model.Count Style="display:block" />
<RadzenCompareValidator Style="position:absolute" Popup="true" Component="Count" Text="Count should be less than 10" Operator="CompareOperator.LessThan" Value="10" />
```

View File

@@ -1,83 +0,0 @@
# ContextMenu component
This article demonstrates how to use the ContextMenu component. Use `ContextMenuService` to open and close context menus.
## Show ContextMenu with items
```
@inject ContextMenuService ContextMenuService
<RadzenButton Text="Show context menu" ContextMenu=@(args => ShowContextMenuWithItems(args)) />
@code {
void ShowContextMenuWithItems(MouseEventArgs args)
{
ContextMenuService.Open(args,
new List<ContextMenuItem> {
new ContextMenuItem(){ Text = "Context menu item 1", Value = 1 },
new ContextMenuItem(){ Text = "Context menu item 2", Value = 2 },
new ContextMenuItem(){ Text = "Context menu item 3", Value = 3 },
}, OnMenuItemClick);
}
void OnMenuItemClick(MenuItemEventArgs args)
{
Console.WriteLine($"Menu item with Value={args.Value} clicked");
}
}
```
## Show ContextMenu with custom content
```
@inject ContextMenuService ContextMenuService
<RadzenButton Text="Show context menu" ContextMenu=@(args => ShowContextMenuWithContent(args)) />
@code {
void ShowContextMenuWithContent(MouseEventArgs args) => ContextMenuService.Open(args, ds =>
@<RadzenMenu Click="OnMenuItemClick">
<RadzenMenuItem Text="Item1" Value="1"></RadzenMenuItem>
<RadzenMenuItem Text="Item2" Value="2"></RadzenMenuItem>
<RadzenMenuItem Text="More items" Value="3">
<RadzenMenuItem Text="More sub items" Value="4">
<RadzenMenuItem Text="Item1" Value="5"></RadzenMenuItem>
<RadzenMenuItem Text="Item2" Value="6"></RadzenMenuItem>
</RadzenMenuItem>
</RadzenMenuItem>
</RadzenMenu>);
void OnMenuItemClick(MenuItemEventArgs args)
{
Console.WriteLine($"Menu item with Value={args.Value} clicked");
}
}
```
## Show ContextMenu for HTML element
```
@inject ContextMenuService ContextMenuService
<button @oncontextmenu=@(args => ShowContextMenuWithContent(args)) @oncontextmenu:preventDefault="true">
Show context menu
</button>
@code {
void ShowContextMenuWithContent(MouseEventArgs args) => ContextMenuService.Open(args, ds =>
@<RadzenMenu Click="OnMenuItemClick">
<RadzenMenuItem Text="Item1" Value="1"></RadzenMenuItem>
<RadzenMenuItem Text="Item2" Value="2"></RadzenMenuItem>
<RadzenMenuItem Text="More items" Value="3">
<RadzenMenuItem Text="More sub items" Value="4">
<RadzenMenuItem Text="Item1" Value="5"></RadzenMenuItem>
<RadzenMenuItem Text="Item2" Value="6"></RadzenMenuItem>
</RadzenMenuItem>
</RadzenMenuItem>
</RadzenMenu>);
void OnMenuItemClick(MenuItemEventArgs args)
{
Console.WriteLine($"Menu item with Value={args.Value} clicked");
}
}
```

View File

@@ -1,387 +0,0 @@
# DataGrid component
This article demonstrates how to use the DataGrid component.
## Data-binding
To display data in DataGrid component you need to set collection of items (`IEnumerable<>`) to `Data` property and define collection of `RadzenDataGridColumn` in `Columns`. DataGrid component can perform server-side sorting, paging and filtering when bound to __IQueryable__ or using `LoadData` event. Grouping will not be performed server-side - only on current page data if paging is enabled.
### Populate data when initialized
```
<RadzenDataGrid Data="@customers" TItem="Customer">
<Columns>
<RadzenDataGridColumn TItem="Customer" Property="CustomerID" Title="Customer ID" />
<RadzenDataGridColumn TItem="Customer" Property="CompanyName" Title="Company Name" />
<RadzenDataGridColumn TItem="Customer" Property="ContactName" Title="Contact Name" />
</Columns>
</RadzenDataGrid>
@code {
IEnumerable<Customer> customers;
protected override void OnInitialized()
{
customers = dbContext.Customers.ToList();
}
}
```
### Populate data on demand using LoadData event.
```
@using System.Linq.Dynamic.Core
@inject NorthwindContext dbContext
<RadzenDataGrid Data="@customers" Count="@count" TItem="Customer" LoadData="@LoadData">
<Columns>
<RadzenDataGridColumn TItem="Customer" Property="CustomerID" Title="Customer ID" />
<RadzenDataGridColumn TItem="Customer" Property="CompanyName" Title="Company Name" />
<RadzenDataGridColumn TItem="Customer" Property="ContactName" Title="Contact Name" />
</Columns>
</RadzenDataGrid>
@code {
IEnumerable<Customer> customers;
int count;
void LoadData(LoadDataArgs args)
{
// This demo is using https://dynamic-linq.net
var query = dbContext.Customers.AsQueryable();
if (!string.IsNullOrEmpty(args.Filter))
{
// Filter via the Where method
query = query.Where(args.Filter);
}
if (!string.IsNullOrEmpty(args.OrderBy))
{
// Sort via the OrderBy method
query = query.OrderBy(args.OrderBy);
}
// Important!!! Make sure the Count property of RadzenDataGrid is set.
count = query.Count();
// Perform paging via Skip and Take.
customers = query.Skip(args.Skip.Value).Take(args.Top.Value).ToList();
// Add StateHasChanged(); for DataGrid to update if your LoadData method is async.
}
}
```
## Sorting
Use `AllowSorting` and `AllowMultiColumnSorting` properties to allow and control sorting.
```
<RadzenDataGrid AllowSorting="true" AllowMultiColumnSorting="true" ...
```
By default DataGrid component will perform sorting using `Property` of the column, use `SortProperty` to specify different sort property from the property used to display data in the column. Use `Sortable` column property to enable/disable sorting for specific column. You can use dot notation to specify sub property.
```
...
<Columns>
<RadzenDataGridColumn TItem="Order" Property="CustomerID" Title="Customer ID" Sortable="false" />
<RadzenDataGridColumn TItem="Order" Property="Customer.CompanyName" Title="Company Name" SortProperty="Customer.ContactName" />
...
```
## Paging
Use `AllowPaging` and `PageSize` properties to allow and control paging.
```
<RadzenDataGrid AllowPaging="true" PageSize="5" ...
```
## Filtering
Use `AllowFiltering`, `FilterMode`, `FilterCaseSensitivity` and `LogicalFilterOperator` properties to allow and control filtering.
```
<RadzenDataGrid AllowFiltering="true" FilterMode="FilterMode.Advanced" LogicalFilterOperator="LogicalFilterOperator.Or" ...
```
By default DataGrid component will perform filtering using `Property` of the column, use `FilterProperty` to specify different filter property from the property used to display data in the column. Use `Filterable` column property to enable/disable filtering for specific column. You can use dot notation to specify sub property.
```
...
<Columns>
<RadzenDataGridColumn TItem="Order" Property="CustomerID" Title="Customer ID" Filterable="false" />
<RadzenDataGridColumn TItem="Order" Property="Customer.CompanyName" Title="Company Name" FilterProperty="Customer.ContactName" />
...
```
Advanced filter mode (`FilterMode.Advanced`) allows you to to apply complex filter for each column with two filter values and filter operators while simple filter mode (`FilterMode.Simple`) allows you to apply single `FilterValue` and `FilterOperator`. `LogicalFilterOperator` column property can be used to specify how the two column filters will be applied - with `and` or `or`.
```
...
<Columns>
<RadzenDataGridColumn TItem="Employee" Property="FirstName" Title="First Name"
FilterValue=@("Nan") FilterOperator="FilterOperator.StartsWith"
LogicalFilterOperator="LogicalFilterOperator.Or" />
<RadzenDataGridColumn TItem="Employee" Property="FirstName" Title="First Name"
FilterValue=@("Nan") FilterOperator="FilterOperator.StartsWith"
SecondFilterValue=@("Nan") SecondFilterOperator="FilterOperator.EndsWith"
LogicalFilterOperator="LogicalFilterOperator.And" />
...
```
Use `FilterTemplate` column property to define your own custom filtering template for specific column
```
...
<Columns>
<RadzenDataGridColumn TItem="Employee" Property="TitleOfCourtesy" Title="Title Of Courtesy" FilterValue="@currentTOC">
<FilterTemplate>
<RadzenDropDown @bind-Value="@currentTOC" ... />
</FilterTemplate>
</RadzenDataGridColumn>
...
```
## Grouping
Use `AllowGrouping` property to allow grouping and Groups collection to add/remove groups using `GroupDescriptor` class. By default DataGrid component will perform grouping using `Property` of the column, use `GroupProperty` to specify different group property from the property used to display data in the column. Use `Groupable` column property to enable/disable grouping for specific column. You can use dot notation to specify sub property.
```
<RadzenDataGrid AllowGrouping="true" Data="@employees" TItem="Employee" Render="@OnRender">
<Columns>
<RadzenDataGridColumn TItem="Employee" Property="EmployeeID" Filterable="false" Title="ID" Frozen="true" Width="70px" />
<RadzenDataGridColumn TItem="Employee" Title="Photo" Sortable="false" Filterable="false" Groupable="false" Width="200px" >
<Template Context="data">
<RadzenImage Path="@data.Photo" style="width: 40px; height: 40px; border-radius: 8px;" />
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn TItem="Employee" Property="FirstName" Title="First Name" />
<RadzenDataGridColumn TItem="Employee" Property="LastName" Title="Last Name" Width="150px"/>
</Columns>
</RadzenDataGrid>
@code {
IEnumerable<Employee> employees;
protected override void OnInitialized()
{
employees = dbContext.Employees;
}
void OnRender(DataGridRenderEventArgs<Employee> args)
{
if(args.FirstRender)
{
args.Grid.Groups.Add(new GroupDescriptor(){ Property = "Title" });
StateHasChanged();
}
}
}
```
Use `GroupHeaderTemplate` to customize group headers. The context in this template is `Group` class.
```
<RadzenDataGrid AllowGrouping="true" Data="@employees" TItem="Employee" Render="@OnRender">
<GroupHeaderTemplate>
@context.GroupDescriptor.GetTitle(): @context.Data.Key, Group items count: @context.Data.Count, Last order date: @(context.Data.Items.Cast<Order>().OrderByDescending(o => o.OrderDate).FirstOrDefault()?.OrderDate)
</GroupHeaderTemplate>
...
```
Use `GroupFooterTemplate` to customize group footers for columns. The context in this template is `Group` class.
```
<Columns>
<RadzenDataGridColumn TItem="Order" Property="Freight" Title="Freight">
<GroupFooterTemplate>
Group amount: <b>@String.Format(new System.Globalization.CultureInfo("en-US"), "{0:C}", context.Data.Items.Cast<Order>().Sum(o => o.Freight))</b>
</GroupFooterTemplate>
</RadzenDataGridColumn>
...
```
## Columns
Use `Template`, `FooterTemplate` and `HeaderTemplate` to specify custom template for data, footer and header cells.
```
...
<Columns>
<RadzenDataGridColumn TItem="Order">
<HeaderTemplate>
Nr.
</HeaderTemplate>
<Template Context="data">
@(orders.IndexOf(data) + 1)
</Template>
<FooterTemplate>
Displayed orders: <b>@ordersGrid.View.Count()</b> of <b>@orders.Count()</b>
</FooterTemplate>
</RadzenDataGridColumn>
...
```
Use `AllowColumnResize` and `AllowColumnReorder` to allow columns resize and reorder. Use column `Resizable` and `Reorderable` properties to enable/disable resize and/or reorder for specific column. Use `ColumnWidth` to specify width for all columns or column `Width` to specify width for specific column. Use `TextAlign` column property to specify column alignment for data, header and footer cells. Set `Frozen` column property to disable horizontal scroll for specific column. Use `OnColumnResized` and `ColumnReordered` events to catch if a column is resized or reordered.
```
<RadzenDataGrid AllowColumnResize="true" AllowColumnReorder="true" ColumnWidth="200px"
ColumnResized=@OnColumnResized ColumnReordered="@OnColumnReordered">
<Columns>
<RadzenDataGridColumn TItem="Employee" Property="EmployeeID" Title="ID" Resizable="true" Reorderable="false" Frozen="true" />
<RadzenDataGridColumn TItem="Employee" Property="FirstName" Title="FirstName" Width="50px" TextAlign="TextAlign.Center" />
...
```
## In-line editing
Use `EditTemplate` to specify cell template when the row is in edit mode. Use DataGrid `EditRow()`, `CancelEditRow()` and `UpdateRow()` to edit, update or cancel changes for specific data item/row. Use DataGrid `EditMode` property to specify if multiple rows or single row can be edited at once.
```
...
<RadzenDataGrid @ref="ordersGrid" EditMode="DataGridEditMode.Single"
Data="@orders" TItem="Order" RowUpdate="@OnUpdateRow" RowCreate="@OnCreateRow">
<Columns>
<RadzenDataGridColumn Width="200px" TItem="Order" Property="Customer.CompanyName" Title="Customer">
<EditTemplate Context="order">
<RadzenDropDown @bind-Value="order.CustomerID" Data="@customers" TextProperty="CompanyName" ValueProperty="CustomerID" />
</EditTemplate>
</RadzenDataGridColumn>
<RadzenDataGridColumn TItem="Order" Context="order" Filterable="false" Sortable="false" TextAlign="TextAlign.Center" Width="100px">
<Template Context="order">
<RadzenButton Icon="edit" Size="ButtonSize.Small" Click="@(args => EditRow(order))" @onclick:stopPropagation="true" />
</Template>
<EditTemplate Context="order">
<RadzenButton Icon="save" Size="ButtonSize.Small" Click="@((args) => SaveRow(order))" />
<RadzenButton Icon="cancel" Size="ButtonSize.Small" ButtonStyle="ButtonStyle.Secondary" Click="@((args) => CancelEdit(order))" />
</EditTemplate>
</RadzenDataGridColumn>
...
```
## Virtualization
Use `AllowVirtualization` to allow virtualization. It is supported for both __IQueryable__ or using `LoadData` event data binding. It is important to specify height for the DataGrid component.
```
<RadzenDataGrid Data="@orderDetails" TItem="OrderDetail" AllowVirtualization="true" Style="height:400px" ...
```
## Hierarchy
Use DataGrid `Template` property to define child content when the row is expanded. Use `RowRender` event to set if a row is expandable or not and use `ExpandRow()` method of the DataGrid to expand desired row/item. Use `ExpandMode` to specify if multiple or single rows can be expanded at once.
```
<RadzenDataGrid @ref="grid" RowRender="@RowRender" ExpandMode="DataGridExpandMode.Single" Data="@orders" TItem="Order">
...
<Template Context="order">
<RadzenDataGrid Data="@order.OrderDetails" TItem="OrderDetail">
<Columns>
<RadzenDataGridColumn TItem="OrderDetail" Property="Order.CustomerID" Title="Order" />
<RadzenDataGridColumn TItem="OrderDetail" Property="Product.ProductName" Title="Product" />
<RadzenDataGridColumn TItem="OrderDetail" Property="UnitPrice" Title="Unit Price">
<Template Context="detail">
@String.Format(new System.Globalization.CultureInfo("en-US"), "{0:C}", detail.UnitPrice)
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn TItem="OrderDetail" Property="Quantity" Title="Quantity" />
<RadzenDataGridColumn TItem="OrderDetail" Property="Discount" Title="Discount">
<Template Context="detail">
@String.Format("{0}%", detail.Discount * 100)
</Template>
</RadzenDataGridColumn>
</Columns>
</RadzenDataGrid>
...
@code {
IEnumerable<Order> orders;
RadzenDataGrid<Order> grid;
protected override void OnInitialized()
{
orders = dbContext.Orders.Include("Customer").Include("Employee").Include("OrderDetails").Include("OrderDetails.Product").ToList();
}
void RowRender(RowRenderEventArgs<Order> args)
{
args.Expandable = args.Data.ShipCountry == "France" || args.Data.ShipCountry == "Brazil";
}
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
grid.ExpandRow(orders.FirstOrDefault());
StateHasChanged();
}
base.OnAfterRender(firstRender);
}
}
```
## Selection
Bind DataGrid `Value` property or assign callback for `RowSelect` event to enable selection. Use `SelectionMode` to specify if selecting of single or multiple items is allowed.
```
<RadzenDataGrid Data="@employees" TItem="Employee" SelectionMode="DataGridSelectionMode.Single" @bind-Value=@selectedEmployees>
<Columns>
...
@code {
IEnumerable<Employee> employees;
IList<Employee> selectedEmployees;
void ClearSelection()
{
selectedEmployees = null;
}
protected override void OnInitialized()
{
employees = dbContext.Employees;
selectedEmployees = employees.Take(1).ToList();
}
}
```
## Conditional formatting
Use `RowRender` and `CellRender` events to specify various row/cell attributes.
```
<RadzenDataGrid Data="@orderDetails" TItem="OrderDetail" RowRender="@RowRender" CellRender="@CellRender">
...
@code {
IEnumerable<OrderDetail> orderDetails;
protected override void OnInitialized()
{
orderDetails = dbContext.OrderDetails.Include("Product").ToList();
}
void RowRender(RowRenderEventArgs<OrderDetail> args)
{
args.Attributes.Add("style", $"font-weight: {(args.Data.Quantity > 20 ? "bold" : "normal")};");
}
void CellRender(DataGridCellRenderEventArgs<OrderDetail> args)
{
if (args.Column.Property == "Quantity")
{
args.Attributes.Add("style", $"background-color: {(args.Data.Quantity > 20 ? "#ff6d41" : "white")};");
if (args.Data.Discount == 0)
{
args.Attributes.Add("colspan", 2);
}
}
if (args.Column.Property == "OrderID")
{
if (args.Data.OrderID == 10248 && args.Data.ProductID == 11 || args.Data.OrderID == 10250 && args.Data.ProductID == 41)
{
args.Attributes.Add("rowspan", 3);
}
if (args.Data.OrderID == 10249 && args.Data.ProductID == 14 || args.Data.OrderID == 10251 && args.Data.ProductID == 22)
{
args.Attributes.Add("rowspan", 2);
}
}
}
```

View File

@@ -1,57 +0,0 @@
# DataList component
This article demonstrates how to use the DataList component.
## Data-binding
To display data in DataList component you need to set collection of items (`IEnumerable<>`) to `Data` property. DataGrid component can perform server-side paging when bound to __IQueryable__ or using `LoadData` event.
### Populate data when initialized
```
@inject NorthwindContext dbContext
<RadzenDataList WrapItems="true" AllowPaging="true" Data="@orders" TItem="Order">
<Template Context="order">
<div>Company:</div>
<b>@order.Customer?.CompanyName</b>
</Template>
</RadzenDataList>
@code {
IEnumerable<Order> orders;
protected override void OnInitialized()
{
orders = dbContext.Orders.Include("Customer").Include("Employee").ToList();
}
}
```
### Populate data on demand using LoadData event.
```
@using System.Linq.Dynamic.Core
@inject NorthwindContext dbContext
<RadzenDataList WrapItems="true" AllowPaging="true" Data="@orders" Count="@count" TItem="Order" LoadData="@LoadData">
<Template Context="order">
<div>Company:</div>
<b>@order.Customer?.CompanyName</b>
</Template>
</RadzenDataList>
@code {
IEnumerable<Customer> customers;
int count;
void LoadData(LoadDataArgs args)
{
// This demo is using https://dynamic-linq.net
var query = dbContext.Customers.AsQueryable();
count = query.Count();
// Perform paging via Skip and Take.
customers = query.Skip(args.Skip.Value).Take(args.Top.Value).ToList();
}
}
```

View File

@@ -1,57 +0,0 @@
# DatePicker component
This article demonstrates how to use the DatePicker component.
## Get and set the value
As all Radzen Blazor input components the DatePicker has a `Value` property which gets and sets the value of the component.
Use `@bind-Value` to get the user input.
```
<RadzenDatePicker @bind-Value=@value Change=@OnChange />
@code {
DateTime? value = DateTime.Today;
void OnChange(DateTime? value)
{
Console.WriteLine($"Value changed to {value}");
}
}
```
## Use DateFormat property to specify format of the DateTime value displayed in the component input.
```
<RadzenDatePicker @bind-Value=@value DateFormat="d" />
```
## Use ShowTime, ShowSeconds, ShowTimeOkButton and TimeOnly properties to control the time parts visibility of the DatePicker.
```
<RadzenDatePicker @bind-Value=@value ShowTime="true" ShowSeconds="true" ShowTimeOkButton="true" TimeOnly="true" />
```
## Use HoursStep, MinutesStep and SecondsStep properties to set step for the time numeric inputs of the DatePicker.
```
<RadzenDatePicker @bind-Value=@value HoursStep="1.5" MinutesStep="5" SecondsStep="10" />
```
## Use Inline="true" to display just the calendar component of the DatePicker.
```
<RadzenDatePicker @bind-Value=@value Inline="true" />
```
## Use DateRender event to set attributes for the date.
```
<RadzenDatePicker @bind-Value=@value DateRender=@DateRenderSpecial />
@code {
DateTime? value = DateTime.Today;
IEnumerable<DateTime> dates = new DateTime[] { DateTime.Today.AddDays(-1), DateTime.Today.AddDays(1) };
void DateRenderSpecial(DateRenderEventArgs args)
{
if (dates.Contains(args.Date))
{
args.Attributes.Add("style", "background-color: #ff6d41; border-color: white;");
}
args.Disabled = dates.Contains(args.Date);
}
}
```

View File

@@ -1,122 +0,0 @@
# Dialog component
This article demonstrates how to use the Dialog component. Use `DialogService` to open and close dialogs.
# Show inline dialog with custom content
```
@inject DialogService DialogService
<RadzenButton Text="Show dialog with inline Blazor content" Click=@ShowInlineDialog />
@code {
async Task ShowInlineDialog()
{
var result = await DialogService.OpenAsync("Simple Dialog", ds =>
@<div>
<p Style="margin-bottom: 1rem">Confirm?</p>
<div class="row">
<div class="col-md-12">
<RadzenButton Text="Ok" Click="() => ds.Close(true)" Style="margin-bottom: 10px; width: 150px" />
<RadzenButton Text="Cancel" Click="() => ds.Close(false)" ButtonStyle="ButtonStyle.Secondary" Style="margin-bottom: 10px; width: 150px"/>
<RadzenButton Text="Refresh" Click="(() => { orderID = 10249; ds.Refresh(); })" ButtonStyle="ButtonStyle.Info" Style="margin-bottom: 10px; width: 150px"/>
Order ID: @orderID
</div>
</div>
</div>);
Console.WriteLine($"Dialog result: {result}");
}
}
```
# Show component/page as dialog
Use `DialogOptions` to specify various dialog properties and provide parameters as `Dictionary<string, object>`.
```
@inject DialogService DialogService
<RadzenButton Text=@($"Show OrderID: {orderID} details") Click=@OpenOrder />
public async Task OpenOrder()
{
await DialogService.OpenAsync<DialogCardPage>($"Order {orderID}",
new Dictionary<string, object>() { { "OrderID", orderID } },
new DialogOptions() { Width = "700px", Height = "530px", Resizable = true, Draggable = true });
}
```
# Show confirm dialog
```
@inject DialogService DialogService
<RadzenButton Text="Show confirm dialog" Click=@(args => DialogService.Confirm("Are you sure?", "MyTitle", new ConfirmOptions() { OkButtonText = "Yes", CancelButtonText = "No" })) />
```
# Show busy dialog
```
@inject DialogService DialogService
<RadzenButton Text="Show busy dialog with string" Click=@(args => ShowBusyDialog(true)) />
<RadzenButton Text="Show busy dialog with markup" Click=@(args => ShowBusyDialog(false)) />
async Task ShowBusyDialog(bool withMessageAsString)
{
InvokeAsync(async () =>
{
// Simulate background task
await Task.Delay(2000);
// Close the dialog
DialogService.Close();
});
if (withMessageAsString)
{
await BusyDialog("Busy ...");
}
else
{
await BusyDialog();
}
}
async Task BusyDialog()
{
await DialogService.OpenAsync("", ds =>
@<div>
<div class="row">
<div class="col-md-12">
Loading...
</div>
</div>
</div>, new DialogOptions() { ShowTitle = false, Style = "min-height:auto;min-width:auto;width:auto" });
}
```
# Show side dialog
The `DialogService` offers the possibility to open a dialog on the side, instead of the screen center.
```
@inject DialogService DialogService
<RadzenButton Text="Show side dialog" Click=@ShowDialog />
@code {
async Task ShowInlineDialog()
{
var result = await DialogService.OpenSideAsync<DialogCardPage>("Side Dialog", new SideDialogOptions
{
Position = DialogPosition.Right
});
Console.WriteLine($"Dialog result: {result}");
}
}
```
The `SideDialogOptions` class can be used to modify the dialog behavior, by e.g. settings the render position to the left or right side of the screen. The Sie Dialog can be positioned on each side of the screen by setting the `SideDialogOptions.Position` property when opening.
In opposite to the default dialog there can only be one side dialog open at the same time. Opening a second side dialog will close the first opened dialog with a null result!

View File

@@ -1,143 +0,0 @@
# DropDown component
This article demonstrates how to use the DropDown component.
## Get and set the value
As all Radzen Blazor input components the CheckBoxList has a `Value` property which gets and sets the value of the component.
Use `@bind-Value` to get the user input. The `TValue` property should be set to the `Value` property type.
## Data-binding
To display data in DropDown component you need to set collection of items (`IEnumerable<>`) to `Data` property. Optionally you can set `TextProperty` to the string property name of the item in the collection and `ValueProperty` to the property name with unique values in the collection.
### Binding to simple collection
```
<RadzenDropDown TValue="string" Data=@(customers.Select(c => c.CompanyName).Distinct()) Change="@OnChange" />
@code {
IEnumerable<Customer> customers;
protected override void OnInitialized()
{
customers = dbContext.Customers.ToList();
}
void OnChange(object value)
{
var str = value is IEnumerable<object> ? string.Join(", ", (IEnumerable<object>)value) : value;
Console.WriteLine($"Value changed to {str}");
}
}
```
### Binding to list of objects
```
<RadzenDropDown TValue="string" Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID" Change="@OnChange" />
@code {
IEnumerable<Customer> customers;
protected override void OnInitialized()
{
customers = dbContext.Customers.ToList();
}
void OnChange(object value)
{
var str = value is IEnumerable<object> ? string.Join(", ", (IEnumerable<object>)value) : value;
Console.WriteLine($"Value changed to {str}");
}
}
```
### Binding using LoadData event with filtering.
```
<RadzenDropDown TValue="string" Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID" LoadData=@LoadData AllowFiltering="true" />
@code {
IEnumerable<Customer> customers;
void LoadData(LoadDataArgs args)
{
var query = dbContext.Customers.AsQueryable();
if (!string.IsNullOrEmpty(args.Filter))
{
query = query.Where(c => c.CustomerID.ToLower().Contains(args.Filter.ToLower()) || c.ContactName.ToLower().Contains(args.Filter.ToLower()));
}
customers = query.ToList();
InvokeAsync(StateHasChanged);
}
}
```
### Virtualization using IQueryable.
```
<RadzenDropDown TValue="string" AllowVirtualization="true" AllowFiltering="true" Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID" />
@code {
IEnumerable<Customer> customers;
protected override void OnInitialized()
{
customers = dbContext.Customers.ToList();
}
}
```
### Virtualization using LoadData event.
```
<RadzenDropDown TValue="string" AllowVirtualization="true" LoadData=@LoadDataVirtualization AllowFiltering="true" Count="@count"
Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID" />
@code {
IEnumerable<Customer> customers;
void LoadDataVirtualization(LoadDataArgs args)
{
var query = dbContext.Customers.AsQueryable();
if (!string.IsNullOrEmpty(args.Filter))
{
query = query.Where(c => c.CustomerID.ToLower().Contains(args.Filter.ToLower()) || c.ContactName.ToLower().Contains(args.Filter.ToLower()));
}
count = query.Count();
customers = query.Skip(args.Skip.Value).Take(args.Top.Value).ToList();
InvokeAsync(StateHasChanged);
}
}
```
### Multiple selection
Bind `Value` property and use `Multiple` property to control if selection is multiple or not.
```
<RadzenDropDown @bind-Value=@multipleValues Multiple="true"
Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID" Change=@OnChange />
@code {
IEnumerable<Customer> customers;
IEnumerable<string> multipleValues;
protected override void OnInitialized()
{
customers = dbContext.Customers.ToList();
}
void OnChange(object value)
{
var str = value is IEnumerable<object> ? string.Join(", ", (IEnumerable<object>)value) : value;
console.Log($"Value changed to {str}");
}
}
```

View File

@@ -1,208 +0,0 @@
# DropDownDataGrid component
This article demonstrates how to use the DropDownDataGrid component.
## Get and set the value
As all Radzen Blazor input components the CheckBoxList has a `Value` property which gets and sets the value of the component.
Use `@bind-Value` to get the user input. The `TValue` property should be set to the `Value` property type.
## Data-binding
To display data in DropDownDataGrid component you need to set collection of items (`IEnumerable<>`) to `Data` property. Optionally you can set `TextProperty` to the string property name of the item in the collection and `ValueProperty` to the property name with unique values in the collection or define collection of `RadzenDataGridColumn` in `Columns`.
### Binding to simple collection
```
<RadzenDropDownDataGrid TValue="string" Data=@(customers.Select(c => c.CompanyName).Distinct()) Change="@OnChange" />
@code {
IEnumerable<Customer> customers;
protected override void OnInitialized()
{
customers = dbContext.Customers.ToList();
}
void OnChange(object value)
{
var str = value is IEnumerable<object> ? string.Join(", ", (IEnumerable<object>)value) : value;
Console.WriteLine($"Value changed to {str}");
}
}
```
### Binding to list of objects
```
<RadzenDropDownDataGrid TValue="string" Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID" Change="@OnChange" />
@code {
IEnumerable<Customer> customers;
protected override void OnInitialized()
{
customers = dbContext.Customers.ToList();
}
void OnChange(object value)
{
var str = value is IEnumerable<object> ? string.Join(", ", (IEnumerable<object>)value) : value;
Console.WriteLine($"Value changed to {str}");
}
}
```
### Binding using LoadData event with filtering.
```
<RadzenDropDownDataGrid TValue="string" Data=@customers Count=@count TextProperty="CompanyName" ValueProperty="CustomerID" LoadData=@LoadData AllowFiltering="true" />
@code {
IEnumerable<Customer> customers;
void LoadData(LoadDataArgs args)
{
var query = dbContext.Customers.AsQueryable();
if (!string.IsNullOrEmpty(args.Filter))
{
query = query.Where(c => c.CustomerID.ToLower().Contains(args.Filter.ToLower()) || c.ContactName.ToLower().Contains(args.Filter.ToLower()));
}
count = query.Count();
customers = query.ToList();
InvokeAsync(StateHasChanged);
}
}
```
### Virtualization using IQueryable.
```
<RadzenDropDownDataGrid TValue="string" AllowVirtualization="true" AllowFiltering="true" Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID" />
@code {
IEnumerable<Customer> customers;
protected override void OnInitialized()
{
customers = dbContext.Customers.ToList();
}
}
```
### Virtualization using LoadData event.
```
<RadzenDropDownDataGrid TValue="string" AllowVirtualization="true" LoadData=@LoadDataVirtualization AllowFiltering="true" Count="@count"
Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID" />
@code {
IEnumerable<Customer> customers;
void LoadDataVirtualization(LoadDataArgs args)
{
var query = dbContext.Customers.AsQueryable();
if (!string.IsNullOrEmpty(args.Filter))
{
query = query.Where(c => c.CustomerID.ToLower().Contains(args.Filter.ToLower()) || c.ContactName.ToLower().Contains(args.Filter.ToLower()));
}
count = query.Count();
customers = query.Skip(args.Skip.Value).Take(args.Top.Value).ToList();
InvokeAsync(StateHasChanged);
}
}
```
### Columns
Define columns in `Columns` tag.
```
<RadzenDropDownDataGrid TValue="string" Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID">
<Columns>
<RadzenDropDownDataGridColumn Property="CustomerID" Title="CustomerID" Width="100px" />
<RadzenDropDownDataGridColumn Property="CompanyName" Title="CompanyName" Width="200px" />
<RadzenDropDownDataGridColumn Property="City" Title="City" Width="100px" />
<RadzenDropDownDataGridColumn Property="Country" Title="Country" Width="100px" />
</Columns>
</RadzenDropDownDataGrid>
@code {
IEnumerable<Customer> customers;
protected override void OnInitialized()
{
customers = dbContext.Customers.ToList();
}
}
```
### Filtering
Use `AllowFiltering`, `AllowFilteringByAllStringColumns`, `FilterCaseSensitivity` and `FilterOperator` properties to allow and control filtering.
```
<RadzenDropDownDataGrid TValue="string" Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID"
AllowFiltering="true" AllowFilteringByAllStringColumns="true"
FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" FilterOperator="StringFilterOperator.StartsWith">
<Columns>
<RadzenDropDownDataGridColumn Property="CustomerID" Title="CustomerID" Width="100px" />
<RadzenDropDownDataGridColumn Property="CompanyName" Title="CompanyName" Width="200px" />
<RadzenDropDownDataGridColumn Property="City" Title="City" Width="100px" />
<RadzenDropDownDataGridColumn Property="Country" Title="Country" Width="100px" />
</Columns>
</RadzenDropDownDataGrid>
@code {
IEnumerable<Customer> customers;
protected override void OnInitialized()
{
customers = dbContext.Customers.ToList();
}
}
```
### Multiple selection
Bind `Value` property and use `Multiple` property to control if selection is multiple or not.
```
<RadzenDropDownDataGrid @ref="grid" @bind-Value=@multipleValues Multiple="true"
Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID"
Change=@OnChange Style="width:100%">
<Columns>
<RadzenDropDownDataGridColumn Width="40px" Sortable="false">
<HeaderTemplate>
<RadzenCheckBox TriState="false" TValue="bool" Value="@(customers.Any(c => multipleValues != null && multipleValues.Contains(c.CustomerID)))"
Change="@(args => multipleValues = args ? grid.View.Cast<Customer>().Select(c => c.CustomerID) : multipleValues = Enumerable.Empty<string>())" />
</HeaderTemplate>
<Template Context="data">
<RadzenCheckBox TriState="false" Value="@(multipleValues != null && multipleValues.Contains(((Customer)data).CustomerID))" />
</Template>
</RadzenDropDownDataGridColumn>
<RadzenDropDownDataGridColumn Property="CustomerID" Title="CustomerID" Width="100px" />
<RadzenDropDownDataGridColumn Property="CompanyName" Title="CompanyName" Width="200px" />
<RadzenDropDownDataGridColumn Property="City" Title="City" Width="100px" />
<RadzenDropDownDataGridColumn Property="Country" Title="Country" Width="100px" />
</Columns>
</RadzenDropDownDataGrid>
@code {
IEnumerable<Customer> customers;
IEnumerable<string> multipleValues;
protected override void OnInitialized()
{
customers = dbContext.Customers.ToList();
}
void OnChange(object value)
{
var str = value is IEnumerable<object> ? string.Join(", ", (IEnumerable<object>)value) : value;
console.Log($"Value changed to {str}");
}
}
```

View File

@@ -1,47 +0,0 @@
# EmailValidator component
This article demonstrates how to use RadzenEmailValidator.
## Basic usage
RadzenEmailValidator checks if the user input is a valid email address.
To use it perform these steps:
1. Add an input component and set its `Name`. Data-bind its value to a model property via `@bind-Value=@model.Email`.
1. Add RadzenEmailValidator and set its `Component` property to the `Name` of the input component.
> [!IMPORTANT]
> RadzenEmailValidator works only inside [RadzenTemplateForm](templateform.md).
Here is a typical user registration form which checks if the user entered the same password.
```
<RadzenTemplateForm TItem="Registration" Data=@model>
<p>
<RadzenLabel Text="Email" />
<RadzenTextBox Name="Email" @bind-Value=@model.Email />
<RadzenEmailValidator Component="Email" Text="Enter email" />
</p>
<RadzenButton ButtonType="ButtonType.Submit" Text="Submit"></RadzenButton>
</RadzenTemplateForm>
@code {
class Registration
{
public string Email { get; set; }
}
Registration model = new Registration();
}
```
## Conditional validation
To make the validator conditional you can set its `Visible` property. When set to `false` the validator will not run.
## Appearance
By default RadzenEmailValidator appears next to the component it validates.
To make it appear below set its `Style` to `"display:block"`.
```
<RadzenTextBox Name="Email" @bind-Value=@model.Email />
<RadzenEmailValidator Component="Email" Text="Enter email" Style="display:block" />
```
To make it appear as a styled popup set its `Popup` property to `true` and set its CSS position to `absolute`. The validated component should have `display: block` so the validation message appears right below it.
```
<RadzenTextBox Name="Email" @bind-Value=@model.Email Style="display:block" />
<RadzenEmailValidator Component="Email" Text="Enter email" Style="position:absolute" Popup="true" />
```

View File

@@ -1,43 +0,0 @@
# Fieldset component
This article demonstrates how to use the Fieldset component.
## Templates
Use `HeaderTemplate`, `ChildContent` and `SummaryTemplate` to define custom content for Fieldset component parts.
```
<RadzenFieldset>
<HeaderTemplate>
Custom header
</HeaderTemplate>
<ChildContent>
Custom content
</ChildContent>
<SummaryTemplate>
Custom summary
</SummaryTemplate>
</RadzenFieldset>
```
## Expand/Collapse
Use `AllowCollapse` property to allow expand/collapse and `Expand` and `Collapse` callbacks to catch if Fieldset component is expanded or collapsed.
```
<RadzenFieldset AllowCollapse="true" Expand=@(() => Change("Fieldset expanded")) Collapse=@(() => Change("Fieldset collapsed"))>
<HeaderTemplate>
Custom header
</HeaderTemplate>
<ChildContent>
Custom content
</ChildContent>
<SummaryTemplate>
Custom summary
</SummaryTemplate>
</RadzenFieldset>
@code {
void Change(string text)
{
Console.WriteLine($"{text}");
}
}
```

View File

@@ -1,23 +0,0 @@
# FileInput component
This article demonstrates how to use the FileInput component. The FileInput component is used to upload files as a part of a TemplateForm component. Files are uploaded as Data URI to be saved in a database table as base64 encoded string.
## Get and set the value
As all Radzen Blazor input components the FileInput has a `Value` property which gets and sets the value of the component.
Use `@bind-Value` to get the user input.
```
<RadzenFileInput @bind-Value=@firstEmployee.Photo TValue="string" Change=@OnChange />
@code {
Employee firstEmployee;
protected override async Task OnInitializedAsync()
{
firstEmployee = await Task.FromResult(dbContext.Employees.FirstOrDefault());
}
void OnChange(string value)
{
Console.WriteLine($"Value changed to {value}");
}
}
```

View File

@@ -1,33 +0,0 @@
# GoogleMap component
This article demonstrates how to use the GoogleMap component.
```
<h3>Show marker for Madrid
<RadzenCheckBox @bind-Value=@showMadridMarker />
</h3>
<RadzenGoogleMap style="height: 400px" Zoom=@zoom Center=@(new GoogleMapPosition() { Lat = 42.6977, Lng = 23.3219 }) MapClick=@OnMapClick MarkerClick=@OnMarkerClick>
<Markers>
<RadzenGoogleMapMarker Title="London" Label="London" Position=@(new GoogleMapPosition() { Lat = 51.5074, Lng = 0.1278 }) />
<RadzenGoogleMapMarker Title="Paris " Label="Paris" Position=@(new GoogleMapPosition() { Lat = 48.8566, Lng = 2.3522 }) />
@if (showMadridMarker)
{
<RadzenGoogleMapMarker Title="Madrid " Label="Madrid" Position=@(new GoogleMapPosition() { Lat = 40.4168, Lng = -3.7038 }) />
}
</Markers>
</RadzenGoogleMap>
@code {
int zoom = 3;
bool showMadridMarker;
EventConsole console;
void OnMapClick(GoogleMapClickEventArgs args)
{
console.Log($"Map clicked at Lat: {args.Position.Lat}, Lng: {args.Position.Lng}");
}
void OnMarkerClick(RadzenGoogleMapMarker marker)
{
console.Log($"Map {marker.Title} marker clicked. Marker position -> Lat: {marker.Position.Lat}, Lng: {marker.Position.Lng}");
}
}
```

View File

@@ -1,6 +0,0 @@
# Gravatar component
This article demonstrates how to use the Gravatar component. Use it to display image from specified email.
```
<RadzenGravatar Email="info@radzen.com" />
```

View File

@@ -1,199 +0,0 @@
# HtmlEditor component
This article demonstrates how to use RadzenHtmlEditor.
## Get and set the value
As all Radzen Blazor input components the HtmlEditor has a `Value` property which gets and sets the value of the component.
Use `@bind-Value` to get the user input.
```
<RadzenHtmlEditor @bind-Value=@htmlValue />
@code {
string htmlValue = "<h1>Hello World!!!</h1>";
}
```
## Tools
The HtmlEditor provides various tools for content editing - bold, italic, color, various text formatting etc.
By default all tools are enabled. Here is how to specify a custom set of tools:
```
<RadzenHtmlEditor @bind-Value=@value>
<RadzenHtmlEditorUndo />
<RadzenHtmlEditorRedo />
<RadzenHtmlEditorSeparator />
<RadzenHtmlEditorBold />
<RadzenHtmlEditorItalic />
<RadzenHtmlEditorUnderline />
<RadzenHtmlEditorStrikeThrough />
<RadzenHtmlEditorSeparator />
<RadzenHtmlEditorColor />
<RadzenHtmlEditorBackground />
<RadzenHtmlEditorRemoveFormat />
</RadzenHtmlEditor>
```
### All tools
The Radzen HtmlEditor supports the following tools:
- RadzenHtmlEditorUndo - allows the user to undo the last action (result of other tool, typing or pasting).
- RadzenHtmlEditorRedo - allows the use to redo the last undone action.
- RadzenHtmlEditorSeparator - displays a vertical separator used to delimit group of similar tools.
- RadzenHtmlEditorBold - toggles the bold style of the selected text.
- RadzenHtmlEditorItalic - toggles the italic style of the selected text.
- RadzenHtmlEditorUnderline - toggles the underline style of the selected text.
- RadzenHtmlEditorStrikeThrough - toggles the strikethrough style of the selected text.
- RadzenHtmlEditorAlignLeft - toggles left text alignment.
- RadzenHtmlEditorAlignCenter - toggles center text alignment.
- RadzenHtmlEditorAlignRight - toggles right text alignment.
- RadzenHtmlEditorJustify - toggles justified text alignment.
- RadzenHtmlEditorIndent - indents the selected text.
- RadzenHtmlEditorOutdent - outdents the selected text.
- RadzenHtmlEditorUnorderedList - inserts unordered (bullet) list.
- RadzenHtmlEditorOrderedList - inserts ordered (numbered) list.
- RadzenHtmlEditorColor - sets the foreground color of the selected text.
- RadzenHtmlEditorBackground - sets the background color of the selected text.
- RadzenHtmlEditorRemoveFormat - removes the visual styling of the selected text.
- RadzenHtmlEditorSource - edit the HTML source as text.
- RadzenHtmlEditorSubscript - converts the selected text to subscript.
- RadzenHtmlEditorSuperscript - converts the selected text to superscript
- RadzenHtmlEditorLink - inserts a hyperlink.
- RadzenHtmlEditorUnlink - removes a hyperlink.
- RadzenHtmlEditorImage - allows the user to insert an image by either uploading a file or selecting a URL. Requires File upload to be implemented and the `UploadUrl` property of the HtmlEditor to be set.
- RadzenHtmlEditorFontName - set the font of the selected text.
- RadzenHtmlEditorFontSize - set the font size of the selected text.
- RadzenHtmlEditorFormatBlock - allows the user to format the selected text as heading or paragraph.
- RadzenHtmlEditorCustomTool - allows the developer to implement a [custom tool](#custom-tools).
### Default tools
By default RadzenHtmlEditor uses these tools:
```
<RadzenHtmlEditorUndo />
<RadzenHtmlEditorRedo />
<RadzenHtmlEditorSeparator />
<RadzenHtmlEditorBold />
<RadzenHtmlEditorItalic />
<RadzenHtmlEditorUnderline />
<RadzenHtmlEditorStrikeThrough />
<RadzenHtmlEditorSeparator />
<RadzenHtmlEditorAlignLeft />
<RadzenHtmlEditorAlignCenter />
<RadzenHtmlEditorAlignRight />
<RadzenHtmlEditorJustify />
<RadzenHtmlEditorSeparator />
<RadzenHtmlEditorIndent />
<RadzenHtmlEditorOutdent />
<RadzenHtmlEditorUnorderedList />
<RadzenHtmlEditorOrderedList />
<RadzenHtmlEditorSeparator />
<RadzenHtmlEditorColor />
<RadzenHtmlEditorBackground />
<RadzenHtmlEditorRemoveFormat />
<RadzenHtmlEditorSeparator />
<RadzenHtmlEditorSubscript />
<RadzenHtmlEditorSuperscript />
<RadzenHtmlEditorSeparator />
<RadzenHtmlEditorLink />
<RadzenHtmlEditorUnlink />
<RadzenHtmlEditorImage />
<RadzenHtmlEditorFontName />
<RadzenHtmlEditorFontSize />
<RadzenHtmlEditorFormatBlock />
<RadzenHtmlEditorSeparator />
<RadzenHtmlEditorSource />
```
### Custom tools
RadzenHtmlEditor allows the developer to create custom tools via the `RadzenHtmlEditorCustomTool` tag.
In its basic form you create a button and handle the `Execute` event of the HtmlEditor to implement the command.
```
<RadzenHtmlEditor Execute=@OnExecute>
<RadzenHtmlEditorCustomTool CommandName="InsertToday" Icon="today" Title="Insert today" />
</RadzenHtmlEditor>
@code {
async Task OnExecute(HtmlEditorExecuteEventArgs args)
{
if (args.CommandName == "InsertToday")
{
var date = DateTime.Now;
await args.Editor.ExecuteCommandAsync(HtmlEditorCommands.InsertHtml, $"<strong>{date.ToLongDateString()}</strong>");
}
}
}
```
You can also specify custom UI via the `Template` of the RadzenHtmlEditorCustomTool.
```
<RadzenHtmlEditor>
<RadzenHtmlEditorCustomTool>
<Template Context="editor">
<RadzenDatePicker Change=@(args => OnDateChange(args, editor)) TValue="DateTime" />
</Template>
</RadzenHtmlEditorCustomTool>
</RadzenHtmlEditor>
@code {
async Task OnDateChange(DateTime? date, RadzenHtmlEditor editor)
{
if (date != null)
{
await editor.ExecuteCommandAsync(HtmlEditorCommands.InsertHtml, $"<strong>{date.Value.ToLongDateString()}</strong>");
}
}
}
```
## Upload files
RadzenHtmlEditor requires file upload support to be implemented for uploading and pasting images. Here is a minimal implementation
that stores the uploaded files in the `wwwroot` directory of the application and uses GUID for the file names to avoid naming conflicts.
# [Page](#tab/page)
```
<RadzenHtmlEditor UploadUrl="upload/image" />
```
# [Controller](#tab/controller)
```
using System;
using System.IO;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Hosting;
namespace YourApplicationNamespace.Controllers
{
public partial class UploadController : Controller
{
private readonly IWebHostEnvironment environment;
public UploadController(IWebHostEnvironment environment)
{
this.environment = environment;
}
[HttpPost("upload/image")]
public IActionResult Image(IFormFile file)
{
try
{
var fileName = $"{Guid.NewGuid()}{Path.GetExtension(file.FileName)}";
using (var stream = new FileStream(Path.Combine(environment.WebRootPath, fileName), FileMode.Create))
{
// Save the file
file.CopyTo(stream);
// Return the URL of the file
var url = Url.Content($"~/{fileName}");
return Ok(new { Url = url });
}
}
catch (Exception ex)
{
return StatusCode(500, ex.Message);
}
}
}
}
```

View File

@@ -1,17 +0,0 @@
# Icon component
This article demonstrates how to use the Icon component. Use it to display icons from Material Icons font.
```
<RadzenIcon Icon="facebook" />
<RadzenIcon Icon="accessibility" />
<RadzenIcon Icon="3d_rotation" />
<RadzenIcon Icon="accessible" />
...
```
## Style the Icon
The Property `IconStyle` allows to modify the icons foreground color. It offers the standard styles defined by the theme.
```
<RadzenIcon Icon="accessibility" IconStyle="IconStyle.Primary">
```

View File

@@ -1,10 +0,0 @@
# Image component
This article demonstrates how to use the Image component. Use it to display images from application assets or external URL.
```
Image from application assets
<RadzenImage Path="images/hero.png" />
Image from external URL
<RadzenImage Path="https://www.radzen.com/assets/hero-40b90af93c7bda2d44608c74e2b8eeb6785e273e02340ec44583d097b5dfb896.png" />
```

View File

@@ -1,16 +0,0 @@
# Label component
This article demonstrates how to use the Label component. Use `Component` property to associate Label with input component with specific Name.
## Label with plain-text content
```
<RadzenLabel Text="Some text" Component="CheckBox1" />
<RadzenCheckBox Name="CheckBox1" />
```
## Label with HTML content
```
<RadzenLabel Component="CheckBox1">Some <strong>text</strong></RadzenLabel>
<RadzenCheckBox Name="CheckBox1" />
```

View File

@@ -1,47 +0,0 @@
# LengthValidator component
This article demonstrates how to use RadzenLengthValidator.
## Basic usage
RadzenLengthValidator checks if the user input is within specified length.
To use it perform these steps:
1. Add an input component and set its `Name`. Data-bind its value to a model property via `@bind-Value=@model.FirstName`.
1. Add RadzenLengthValidator and set its `Component` property to the `Name` of the input component. Set `Min`, `Max` or both
to specify the valid string length.
> [!IMPORTANT]
> RadzenLengthValidator works only inside [RadzenTemplateForm](templateform.md).
```
<RadzenTemplateForm TItem="Registration" Data=@model>
<p>
<RadzenTextBox style="display: block" Name="FirstName" @bind-Value=@model.FirstName />
<RadzenLengthValidator Component="FirstName" Min="3" Text="First name should be at least 3 characters" />
<RadzenLengthValidator Component="FirstName" Max="10" Text="First name should be at most 10 characters" />
</p>
<RadzenButton ButtonType="ButtonType.Submit" Text="Submit"></RadzenButton>
</RadzenTemplateForm>
@code {
class Registration
{
public string FirstName { get; set; }
}
Registration model = new Registration();
}
```
## Conditional validation
To make the validator conditional you can set its `Visible` property. When set to `false` the validator will not run.
## Appearance
By default RadzenLengthValidator appears next to the component it validates.
To make it appear below set its `Style` to `"display:block"`.
```
<RadzenTextBox Name="FirstName" @bind-Value=@model.FirstName />
<RadzenLengthValidator Style="display:block" Component="FirstName" Min="3" Text="First name should be at least 3 characters" />
```
To make it appear as a styled popup set its `Popup` property to `true` and set its CSS position to `absolute`. The validated component should have `display: block` so the validation message appears right below it.
```
<RadzenTextBox Name="FirstName" @bind-Value=@model.FirstName Style="display:block" />
<RadzenLengthValidator Popup="true" Style="position:absolute" Component="FirstName" Min="3" Text="First name should be at least 3 characters" />
```

View File

@@ -1,13 +0,0 @@
# Link component
This article demonstrates how to use the Link component. Use `Path` and `Target` properties to specify Link component navigation.
```
Link to path in application
<RadzenLink Path="buttons" Text="Go to Buttons page" />
Link to path in application with icon
<RadzenLink Icon="accessibility" Path="button" Text="Go to the Button component page" />
Link to URL
<RadzenLink Path="https://www.radzen.com" Text="Go to url" Target="_blank" />
```

View File

@@ -1,143 +0,0 @@
# ListBox component
This article demonstrates how to use the ListBox component.
## Get and set the value
As all Radzen Blazor input components the CheckBoxList has a `Value` property which gets and sets the value of the component.
Use `@bind-Value` to get the user input. The `TValue` property should be set to the `Value` property type.
## Data-binding
To display data in ListBox component you need to set collection of items (`IEnumerable<>`) to `Data` property. Optionally you can set `TextProperty` to the string property name of the item in the collection and `ValueProperty` to the property name with unique values in the collection.
### Binding to simple collection
```
<RadzenListBox TValue="string" Data=@(customers.Select(c => c.CompanyName).Distinct()) Change="@OnChange" />
@code {
IEnumerable<Customer> customers;
protected override void OnInitialized()
{
customers = dbContext.Customers.ToList();
}
void OnChange(object value)
{
var str = value is IEnumerable<object> ? string.Join(", ", (IEnumerable<object>)value) : value;
Console.WriteLine($"Value changed to {str}");
}
}
```
### Binding to list of objects
```
<RadzenListBox TValue="string" Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID" Change="@OnChange" />
@code {
IEnumerable<Customer> customers;
protected override void OnInitialized()
{
customers = dbContext.Customers.ToList();
}
void OnChange(object value)
{
var str = value is IEnumerable<object> ? string.Join(", ", (IEnumerable<object>)value) : value;
Console.WriteLine($"Value changed to {str}");
}
}
```
### Binding using LoadData event with filtering.
```
<RadzenListBox TValue="string" Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID" LoadData=@LoadData AllowFiltering="true" />
@code {
IEnumerable<Customer> customers;
void LoadData(LoadDataArgs args)
{
var query = dbContext.Customers.AsQueryable();
if (!string.IsNullOrEmpty(args.Filter))
{
query = query.Where(c => c.CustomerID.ToLower().Contains(args.Filter.ToLower()) || c.ContactName.ToLower().Contains(args.Filter.ToLower()));
}
customers = query.ToList();
InvokeAsync(StateHasChanged);
}
}
```
### Virtualization using IQueryable.
```
<RadzenListBox TValue="string" AllowVirtualization="true" AllowFiltering="true" Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID" />
@code {
IEnumerable<Customer> customers;
protected override void OnInitialized()
{
customers = dbContext.Customers.ToList();
}
}
```
### Virtualization using LoadData event.
```
<RadzenListBox TValue="string" AllowVirtualization="true" LoadData=@LoadDataVirtualization AllowFiltering="true" Count="@count"
Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID" />
@code {
IEnumerable<Customer> customers;
void LoadDataVirtualization(LoadDataArgs args)
{
var query = dbContext.Customers.AsQueryable();
if (!string.IsNullOrEmpty(args.Filter))
{
query = query.Where(c => c.CustomerID.ToLower().Contains(args.Filter.ToLower()) || c.ContactName.ToLower().Contains(args.Filter.ToLower()));
}
count = query.Count();
customers = query.Skip(args.Skip.Value).Take(args.Top.Value).ToList();
InvokeAsync(StateHasChanged);
}
}
```
### Multiple selection
Bind `Value` property and use `Multiple` property to control if selection is multiple or not.
```
<RadzenListBox @bind-Value=@multipleValues Multiple="true"
Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID" Change=@OnChange />
@code {
IEnumerable<Customer> customers;
IEnumerable<string> multipleValues;
protected override void OnInitialized()
{
customers = dbContext.Customers.ToList();
}
void OnChange(object value)
{
var str = value is IEnumerable<object> ? string.Join(", ", (IEnumerable<object>)value) : value;
console.Log($"Value changed to {str}");
}
}
```

View File

@@ -1,44 +0,0 @@
# Login component
This article demonstrates how to use the Login component. Should be used together with RadzenTemplateForm with Data property set.
## Events
Use `Login`, `` and `` to catch events raised by Login component.
```
<RadzenTemplateForm Data=@("SimpleLogin") Action="http://www.google.com">
<RadzenLogin AllowRegister="true" AllowResetPassword="true"
Login=@OnLogin Register=@OnRegister ResetPassword=@OnResetPassword />
</RadzenTemplateForm>
@code {
string userName = "admin";
string password = "admin";
void OnLogin(LoginArgs args)
{
Console.WriteLine($"Username: {args.Username} and password: {args.Password}");
}
void OnRegister(string name)
{
Console.WriteLine($"{name} -> Register");
}
void OnResetPassword(string value, string name)
{
Console.WriteLine($"{name} -> ResetPassword for user: {value}");
}
}
```
## Localization
```
<RadzenTemplateForm Data=@("Localization")>
<RadzenLogin AllowRegister="true" AllowResetPassword="true"
LoginText="Einloggen" UserText="Benutzername" PasswordText="Passwort"
UserRequired="Benutzername erforderlich"
PasswordRequired="Passwort erforderlich"
RegisterText="Registrieren"
RegisterMessageText="Sie haben noch keinen Account?"
ResetPasswordText="Passwort zurücksetzen" />
</RadzenTemplateForm>
```

View File

@@ -1,70 +0,0 @@
# Mask component
This article demonstrates how to use the Mask component.
## Get and set the value
As all Radzen Blazor input components the Mask has a `Value` property which gets and sets the value of the component.
Use `@bind-Value` to get the user input. Use `Mask`, `Pattern` and `Placeholder` properties to define and hint Mask component input.
## Telephone mask
```
<RadzenMask Mask="(***) ***-****" Pattern="[^0-9]" Placeholder="(000) 000-0000" Name="Phone" @bind-Value=@obj.Phone Change=@OnChange />
@code {
public class MyObject
{
public string Phone { get; set; }
public string CardNr { get; set; }
public string SSN { get; set; }
}
MyObject obj = new MyObject();
void OnChange(string value)
{
Console.WriteLine($"Value changed to {value}");
}
}
```
## Credit Card mask
```
<RadzenMask Mask="**** **** **** ****" Pattern="[^0-9]" Placeholder="0000 0000 0000 0000" Name="CardNr" @bind-Value=@obj.CardNr Change=@OnChange />
@code {
public class MyObject
{
public string Phone { get; set; }
public string CardNr { get; set; }
public string SSN { get; set; }
}
MyObject obj = new MyObject();
void OnChange(string value)
{
Console.WriteLine($"Value changed to {value}");
}
}
```
## SSN mask
```
<RadzenMask Mask="***-**-****" Pattern="[^0-9]" Placeholder="000-00-0000" Name="SSN" @bind-Value=@obj.SSN Change=@OnChange />
@code {
public class MyObject
{
public string Phone { get; set; }
public string CardNr { get; set; }
public string SSN { get; set; }
}
MyObject obj = new MyObject();
void OnChange(string value)
{
Console.WriteLine($"Value changed to {value}");
}
}
```

View File

@@ -1,46 +0,0 @@
# Menu component
This article demonstrates how to use the Menu component.
```
<RadzenMenu>
<RadzenMenuItem Text="General" Icon="home">
<RadzenMenuItem Text="Buttons" Path="buttons" Icon="account_circle"></RadzenMenuItem>
<RadzenMenuItem Text="Menu" Path="menu" Icon="line_weight"></RadzenMenuItem>
<RadzenMenuItem Text="FileInput" Path="fileinput" Icon="attach_file"></RadzenMenuItem>
<RadzenMenuItem Text="Dialog" Path="dialog" Icon="perm_media"></RadzenMenuItem>
<RadzenMenuItem Text="Notification" Path="notification" Icon="announcement"></RadzenMenuItem>
</RadzenMenuItem>
<RadzenMenuItem Text="Inputs" Icon="payment">
<RadzenMenuItem Text="CheckBox" Path="checkbox" Icon="check_circle"></RadzenMenuItem>
<RadzenMenuItem Text="TextBox" Path="textbox" Icon="input"></RadzenMenuItem>
<RadzenMenuItem Text="TextArea" Path="textarea" Icon="description"></RadzenMenuItem>
<RadzenMenuItem Text="Password" Path="password" Icon="payment"></RadzenMenuItem>
<RadzenMenuItem Text="Numeric" Path="numeric" Icon="aspect_ratio"></RadzenMenuItem>
<RadzenMenuItem Text="DatePicker" Path="datepicker" Icon="date_range"></RadzenMenuItem>
</RadzenMenuItem>
<RadzenMenuItem Text="Data" Icon="save">
<RadzenMenuItem Text="DataGrid" Path="datagrid" Icon="grid_on"></RadzenMenuItem>
<RadzenMenuItem Text="DataList" Path="datalist" Icon="list"></RadzenMenuItem>
<RadzenMenuItem Text="DropDown" Path="dropdown" Icon="dns"></RadzenMenuItem>
<RadzenMenuItem Text="DropDownDataGrid" Path="dropdown-datagrid" Icon="receipt"></RadzenMenuItem>
<RadzenMenuItem Text="ListBox" Path="listbox" Icon="view_list"></RadzenMenuItem>
<RadzenMenuItem Text="TemplateForm" Path="templateform" Icon="line_style"></RadzenMenuItem>
</RadzenMenuItem>
<RadzenMenuItem Text="Containers" Icon="account_box">
<RadzenMenuItem Text="Tabs" Path="tabs" Icon="tab"></RadzenMenuItem>
<RadzenMenuItem Text="Panel" Path="panel" Icon="content_paste"></RadzenMenuItem>
<RadzenMenuItem Text="Fieldset" Path="fieldset" Icon="account_balance_wallet"></RadzenMenuItem>
<RadzenMenuItem Text="Card" Path="card" Icon="line_style"></RadzenMenuItem>
</RadzenMenuItem>
<RadzenMenuItem Text="More">
<RadzenMenuItem Text="Item1"></RadzenMenuItem>
<RadzenMenuItem Text="Item2"></RadzenMenuItem>
<RadzenMenuItem Text="More items">
<RadzenMenuItem Text="More sub items">
<RadzenMenuItem Text="Item1"></RadzenMenuItem>
<RadzenMenuItem Text="Item2"></RadzenMenuItem>
</RadzenMenuItem>
</RadzenMenuItem>
</RadzenMenuItem>
</RadzenMenu>
```

View File

@@ -1,37 +0,0 @@
# Notification component
This article demonstrates how to use the Notification component. Use `NotificationService` to open and close notifications.
## Show notification with specific `Severity`: Info, Warning, Danger and Success
```
@inject NotificationService NotificationService
<RadzenButton Text="Show info notification" Style="margin-bottom: 20px; width: 200px"
ButtonStyle="ButtonStyle.Info"
Click=@(args => ShowNotification(new NotificationMessage { Severity = NotificationSeverity.Info, Summary = "Info Summary", Detail = "Info Detail", Duration = 4000 })) />
@code {
void ShowNotification(NotificationMessage message)
{
NotificationService.Notify(message);
Console.WriteLine($"{message.Severity} notification");
}
}
```
## Show notification with custom position
```
@inject NotificationService NotificationService
<RadzenButton Text="Show notification with custom position" Style="margin-bottom: 20px;"
Click=@(args => ShowNotification(new NotificationMessage { Style = "position: absolute; left: -1000px;", Severity = NotificationSeverity.Success, Summary = "Success Summary", Detail = "Success Detail", Duration = 40000 })) />
@code {
void ShowNotification(NotificationMessage message)
{
NotificationService.Notify(message);
Console.WriteLine($"{message.Severity} notification");
}
}
```

View File

@@ -1,59 +0,0 @@
# Numeric component
This article demonstrates how to use the Numeric component.
## Get and set the value
As all Radzen Blazor input components the Numeric has a `Value` property which gets and sets the value of the component.
Use `@bind-Value` to get the user input.
## Min and Max
```
<RadzenNumeric TValue="int" Min="1" Max="10" Change=@OnChange />
@code {
void OnChange(int value)
{
Console.WriteLine($"Value changed to {value}");
}
}
```
## Step
```
<RadzenNumeric TValue="double" Placeholder="0.0" Step="0.5" Change=@OnChange />
@code {
void OnChange(double value)
{
Console.WriteLine($"Value changed to {value}");
}
}
```
## Formatted Value
```
<RadzenNumeric TValue="double" Format="0.0000" @bind-Value=@dblValue Placeholder="Enter or clear value" Change="@OnChange />
@code {
double dblValue = 0.0;
void OnChange(double value)
{
Console.WriteLine($"Value changed to {value}");
}
}
```
## Without Up/Down buttons
```
<RadzenNumeric ShowUpDown="false" TValue="int?" @bind-Value=@value Placeholder="Enter or clear value" Change="@OnChange />
@code {
int? value = null;
void OnChange(int? value)
{
Console.WriteLine($"Value changed to {value}");
}
}
```

View File

@@ -1,46 +0,0 @@
# NumericRangeValidator component
This article demonstrates how to use RadzenNumericRangeValidator.
## Basic usage
RadzenNumericRangeValidator checks if the user enters a number within a specified range.
To use it perform these steps:
1. Add an input component and set its `Name`. Data-bind its value to a model property via `@bind-Value=@model.Quantity`.
1. Add RadzenNumericRangeValidator and set its `Component` property to the `Name` of the input component. Set `Min`, `Max` or both
to specify the valid range.
> [!IMPORTANT]
> RadzenNumericRangeValidator works only inside [RadzenTemplateForm](templateform.md).
```
<RadzenTemplateForm TItem="Registration" Data=@model>
<p>
<RadzenNumeric Name="Quantity" @bind-Value=@model.Quantity />
<RadzenNumericRangeValidator Component="Quantity" Min="1" Max="10" Text="Quantity should be between 1 and 10" />
</p>
<RadzenButton ButtonType="ButtonType.Submit" Text="Submit"></RadzenButton>
</RadzenTemplateForm>
@code {
class Model
{
public decimal Quantity { get; set; }
}
Model model = new Model();
}
```
## Conditional validation
To make the validator conditional you can set its `Visible` property. When set to `false` the validator will not run.
## Appearance
By default RadzenNumericRangeValidator appears next to the component it validates.
To make it appear below set its `Style` to `"display:block"`.
```
<RadzenNumeric Name="Quantity" @bind-Value=@model.Quantity />
<RadzenNumericRangeValidator Style="display:block" Component="Quantity" Min="1" Max="10" Text="Quantity should be between 1 and 10" />
```
To make it appear as a styled popup set its `Popup` property to `true` and set its CSS position to `absolute`. The validated component should have `display: block` so the validation message appears right below it.
```
<RadzenNumeric Name="Quantity" Style="display:block" @bind-Value=@model.Quantity />
<RadzenNumericRangeValidator Popup="true" Style="position:absolute" Component="Quantity" Min="1" Max="10" Text="Quantity should be between 1 and 10" />
```

View File

@@ -1,28 +0,0 @@
# Pager component
This article demonstrates how to use the Pager component.
```
<RadzenPager Count="count" PageSize="@pageSize" PageNumbersCount="10" PageChanged="@PageChanged" />
@code {
int pageSize = 6;
int count;
IEnumerable<Order> orders;
protected override void OnInitialized()
{
count = dbContext.Orders.Count();
orders = GetOrders(0, pageSize);
}
void PageChanged(PagerEventArgs args)
{
orders = GetOrders(args.Skip, args.Top);
}
IEnumerable<Order> GetOrders(int skip, int take)
{
return dbContext.Orders.Include("Customer").Include("Employee").Skip(skip).Take(take).ToList();
}
}
```

View File

@@ -1,43 +0,0 @@
# Panel component
This article demonstrates how to use the Panel component.
## Templates
Use `HeaderTemplate`, `ChildContent` and `SummaryTemplate` to define custom content for Panel component parts.
```
<RadzenPanel>
<HeaderTemplate>
Custom header
</HeaderTemplate>
<ChildContent>
Custom content
</ChildContent>
<SummaryTemplate>
Custom summary
</SummaryTemplate>
</RadzenPanel>
```
## Expand/Collapse
Use `AllowCollapse` property to allow expand/collapse and `Expand` and `Collapse` callbacks to catch if Panel component is expanded or collapsed.
```
<RadzenPanel AllowCollapse="true" Expand=@(() => Change("Panel expanded")) Collapse=@(() => Change("Panel collapsed"))>
<HeaderTemplate>
Custom header
</HeaderTemplate>
<ChildContent>
Custom content
</ChildContent>
<SummaryTemplate>
Custom summary
</SummaryTemplate>
</RadzenPanel>
@code {
void Change(string text)
{
Console.WriteLine($"{text}");
}
}
```

View File

@@ -1,46 +0,0 @@
# PanelMenu component
This article demonstrates how to use the PanelMenu component.
```
<RadzenPanelMenu Style="width:300px">
<RadzenPanelMenuItem Text="General" Icon="home">
<RadzenPanelMenuItem Text="Buttons" Path="buttons" Icon="account_circle"></RadzenPanelMenuItem>
<RadzenPanelMenuItem Text="Menu" Path="menu" Icon="line_weight"></RadzenPanelMenuItem>
<RadzenPanelMenuItem Text="FileInput" Path="fileinput" Icon="attach_file"></RadzenPanelMenuItem>
<RadzenPanelMenuItem Text="Dialog" Path="dialog" Icon="perm_media"></RadzenPanelMenuItem>
<RadzenPanelMenuItem Text="Notification" Path="notification" Icon="announcement"></RadzenPanelMenuItem>
</RadzenPanelMenuItem>
<RadzenPanelMenuItem Text="Inputs" Icon="payment">
<RadzenPanelMenuItem Text="CheckBox" Path="checkbox" Icon="check_circle"></RadzenPanelMenuItem>
<RadzenPanelMenuItem Text="TextBox" Path="textbox" Icon="input"></RadzenPanelMenuItem>
<RadzenPanelMenuItem Text="TextArea" Path="textarea" Icon="description"></RadzenPanelMenuItem>
<RadzenPanelMenuItem Text="Password" Path="password" Icon="payment"></RadzenPanelMenuItem>
<RadzenPanelMenuItem Text="Numeric" Path="numeric" Icon="aspect_ratio"></RadzenPanelMenuItem>
<RadzenPanelMenuItem Text="DatePicker" Path="datepicker" Icon="date_range"></RadzenPanelMenuItem>
</RadzenPanelMenuItem>
<RadzenPanelMenuItem Text="Data" Icon="save">
<RadzenPanelMenuItem Text="DataGrid" Path="datagrid" Icon="grid_on"></RadzenPanelMenuItem>
<RadzenPanelMenuItem Text="DataList" Path="datalist" Icon="list"></RadzenPanelMenuItem>
<RadzenPanelMenuItem Text="DropDown" Path="dropdown" Icon="dns"></RadzenPanelMenuItem>
<RadzenPanelMenuItem Text="DropDownDataGrid" Path="dropdown-datagrid" Icon="receipt"></RadzenPanelMenuItem>
<RadzenPanelMenuItem Text="ListBox" Path="listbox" Icon="view_list"></RadzenPanelMenuItem>
<RadzenPanelMenuItem Text="TemplateForm" Path="templateform" Icon="line_style"></RadzenPanelMenuItem>
</RadzenPanelMenuItem>
<RadzenPanelMenuItem Text="Containers" Icon="account_box">
<RadzenPanelMenuItem Text="Tabs" Path="tabs" Icon="tab"></RadzenPanelMenuItem>
<RadzenPanelMenuItem Text="Panel" Path="panel" Icon="content_paste"></RadzenPanelMenuItem>
<RadzenPanelMenuItem Text="Fieldset" Path="fieldset" Icon="account_balance_wallet"></RadzenPanelMenuItem>
<RadzenPanelMenuItem Text="Card" Path="card" Icon="line_style"></RadzenPanelMenuItem>
</RadzenPanelMenuItem>
<RadzenPanelMenuItem Text="More">
<RadzenPanelMenuItem Text="Item1"></RadzenPanelMenuItem>
<RadzenPanelMenuItem Text="Item2"></RadzenPanelMenuItem>
<RadzenPanelMenuItem Text="More items">
<RadzenPanelMenuItem Text="More sub items">
<RadzenPanelMenuItem Text="Item1"></RadzenPanelMenuItem>
<RadzenPanelMenuItem Text="Item2"></RadzenPanelMenuItem>
</RadzenPanelMenuItem>
</RadzenPanelMenuItem>
</RadzenPanelMenuItem>
</RadzenPanelMenu>
```

View File

@@ -1,36 +0,0 @@
# Password component
This article demonstrates how to use the Password component.
## Get and set the value
As all Radzen Blazor input components the Password has a `Value` property which gets and sets the value of the component.
Use `@bind-Value` to get the user input.
```
<RadzenPassword @bind-Value=@user.Password Change=@OnChange />
@code {
ApplicationUser user;
protected override async Task OnInitializedAsync()
{
user = // get the application user;
}
void OnChange(string value)
{
Console.WriteLine($"Value changed to {value}");
}
}
```
## Properties
Use `Disabled`, `ReadOnly`, `Placeholder` and `AutoComplete` properties to control various HTML input type="password" attributes. You can set also arbitrary attributes not exposed as properties.
```
<RadzenPassword Placeholder="Type here .." MaxLength="10" AutoComplete="false" @oninput=@(args => OnChange(args.Value.ToString())) />
@code {
void OnChange(string value)
{
Console.WriteLine($"Value changed to {value}");
}
}
```

View File

@@ -1,18 +0,0 @@
# ProfileMenu component
This article demonstrates how to use the ProfileMenu component.
```
<RadzenProfileMenu>
<Template>
<RadzenGravatar Email="user@example.com">
</RadzenGravatar>
</Template>
<ChildContent>
<RadzenProfileMenuItem Text="Buttons" Path="buttons" Icon="account_circle"></RadzenProfileMenuItem>
<RadzenProfileMenuItem Text="Menu" Path="menu" Icon="line_weight"></RadzenProfileMenuItem>
<RadzenProfileMenuItem Text="FileInput" Path="fileinput" Icon="attach_file"></RadzenProfileMenuItem>
<RadzenProfileMenuItem Text="Dialog" Path="dialog" Icon="perm_media"></RadzenProfileMenuItem>
<RadzenProfileMenuItem Text="Notification" Path="notification" Icon="announcement"></RadzenProfileMenuItem>
</ChildContent>
</RadzenProfileMenu>
```

View File

@@ -1,25 +0,0 @@
# ProgressBar component
This article demonstrates how to use the ProgressBar component.
## Get and set the value
As all Radzen Blazor input components the ProgressBar has a `Value` property which gets and sets the value of the component.
Use `@bind-Value` to get the user input.
```
<RadzenProgressBar @bind-Value="@value" />
@code {
double value = 55;
}
```
## ProgressBar in indeterminate mode
```
<RadzenProgressBar Value="100" ShowValue="false" Mode="ProgressBarMode.Indeterminate" />
```
## ProgressBar in max value > 100
```
<RadzenProgressBar Value="156" Max="200" />
```

View File

@@ -1,140 +0,0 @@
# RadialGauge component
This article demonstrates how to use RadzenRadialGauge.
## Basic usage
Here is basic example that creates a radial gauge with minimal configuration.
```
<RadzenRadialGauge Style="width: 300px; height: 300px">
<RadzenRadialGaugeScale>
<RadzenRadialGaugeScalePointer Value="50" />
</RadzenRadialGaugeScale>
</RadzenRadialGauge>
```
RadzenRadialGaugeScale is used to add a scale and configure its options - min and max value, start and end angle, tick display etc.
RadzenRadialGaugeScalePointer tag adds and configures a pointer of the RadialGaugeScale it is a child of. The key property here is `Value` - it specifies the value the pointer "points" to on the scale.
Radzen Blazor gauges can have multiple scales and every scale can have multiple pointers or values.
## Ranges
The RadzenRadialGaugeScale supports ranges. A range applies a color between two values of the scale. For example this is often used to specify a "dangerous" zone of the scale
which a pointer isn't supposed to go to. A RadzenRadialGaugeScale can have multiple ranges that should not overlap.
```
<RadzenRadialGauge>
<RadzenRadialGaugeScale Min="0" Max="260">
<RadzenRadialGaugeScalePointer Value="50" />
<RadzenRadialGaugeScaleRange From="0" To="90" Fill="green" />
<RadzenRadialGaugeScaleRange From="90" To="140" Fill="orange" />
<RadzenRadialGaugeScaleRange From="140" To="260" Fill="red" />
</RadzenRadialGaugeScale>
</RadzenRadialGauge>
```
## Scale configuration
### Min, max and step
By default the `Min` property of both scale types (Radial and Radial) is set to `0`. `Max` is set to `100` and `Step` is set to `20`.
To override the defaults use the `Min`, `Max` and `Step` properties of the `RadzenRadialGaugeScale` tag.
```
<RadzenRadialGauge Style="width: 300px; height: 300px">
<RadzenRadialGaugeScale Min="100" Max="1000" Step="100">
<RadzenRadialGaugeScalePointer Value="50" />
</RadzenRadialGaugeScale>
</RadzenRadialGauge>
```
### Tick configuration
By default the RadzenRadialGaugeScale does not display ticks. You need to set the `TickPosition` property to `GaugeTickPosition.Outside` or `GaugeTickPosition.Inside`. To hide the ticks altogether use `GaugeTickPosition.None`.
```
<RadzenRadialGauge Style="width: 300px; height: 300px">
<RadzenRadialGaugeScale TickPosition="GaugeTickPosition.Outside">
<RadzenRadialGaugeScalePointer Value="50" />
</RadzenRadialGaugeScale>
</RadzenRadialGauge>
```
Minor ticks are not displayed by default. To display them set the MinorStep property to a value greater than `0`.
```
<RadzenRadialGauge Style="width: 300px; height: 300px">
<RadzenRadialGaugeScale TickPosition="GaugeTickPosition.Outside" MinorStep="5">
<RadzenRadialGaugeScalePointer Value="50" />
</RadzenRadialGaugeScale>
</RadzenRadialGauge>
```
### Change the start and and angles
By default the `StartAngle` property of the gauge scales is set to `-90` and `EndAngle` is set to `90`. This makes
the default shape half a circle. Here is how to create a gauge which is a full circle:
```
<RadzenRadialGauge>
<RadzenRadialGaugeScale StartAngle="0" EndAngle="360">
<RadzenRadialGaugeScalePointer Value="50" />
</RadzenRadialGaugeScale>
</RadzenRadialGauge>
```
### Format the values
The scale ticks labels displays values with default formatting (`ToString()`). This can be customized in two ways - via the `FormatString` or the `Formatter` properties.
`FormatString` supports the [standard .NET Number formats](https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings).
```
<RadzenRadialGauge Style="width: 300px; height: 300px">
<RadzenRadialGaugeScale FormatString="{0:C}">
<RadzenGaugeGaugeScalePointer Value="50" />
</RadzenGaugeGaugeScale>
</RadzenGaugeGauge>
```
```
<RadzenRadialGauge Style="width: 300px; height: 300px">
<RadzenRadialGaugeScale Formatter=@(value => value.ToString())>
<RadzenGaugeGaugeScalePointer Value="50" />
</RadzenGaugeGaugeScale>
</RadzenGaugeGauge>
```
### Change the scale position
You can use the `X` and `Y` property of the scales to change the position of their center. Both properties have a default value of `0.5` which means
that by default the center of a scale is the middle of the gauge. `X` and `Y` are a multiplier of the width and height.
For example you can move the center of the scale to the bottom of the component by setting `Y` to `1`.
```
<RadzenRadialGauge Style="width: 300px; height: 300px">
<RadzenRadialGaugeScale Y="1">
<RadzenGaugeGaugeScalePointer Value="50" />
</RadzenGaugeGaugeScale>
</RadzenGaugeGauge>
```
Using `X` and `Y` is also useful when you have multiple scales - this allows you to prevent them from overlapping which they will do by default.
## Pointer configuration
### Pointer length
By default a RadialGaugeScalePointer is as long as the radius of its scale. You can controll that via the `Length` property which is a multiplier with a default value `1`.
Here is how to make the pointer half the radius:
```
<RadzenRadialGauge>
<RadzenRadialGaugeScale>
<RadzenRadialGaugeScalePointer Value="50" Length="0.5" />
</RadzenRadialGaugeScale>
</RadzenRadialGauge>
```
### Hide the pointer value
By default the `Value` property is displayed below the pointer. You can hide it by setting the `ShowValue` property to `false`.
```
<RadzenRadialGauge>
<RadzenRadialGaugeScale>
<RadzenRadialGaugeScalePointer Value="50" ShowValue="false" />
</RadzenRadialGaugeScale>
</RadzenRadialGauge>
```
### Customize the value display
Use the `Template` property of the pointer to tweak the default value appearance.
```
<RadzenRadialGauge>
<RadzenRadialGaugeScale Min="0" Max="260">
<RadzenRadialGaugeScalePointer Value=@value>
<Template Context="pointer">
<h4>
@pointer.Value <sup>km/h</sup>
</h4>
</Template>
</RadzenRadialGaugeScalePointer>
</RadzenRadialGaugeScale>
</RadzenRadialGauge>
```

View File

@@ -1,69 +0,0 @@
# RadioButtonList component
This article demonstrates how to use the RadioButtonList component.
## Get and set the value
As all Radzen Blazor input components the RadioButtonList has a `Value` property which gets and sets the value of the component.
Use `@bind-Value` to get the user input. The `TValue` property should be set to the `Value` property type.
## Data-binding
To display data in RadioButtonList component you can statically declare items in the markup and/or set collection of items (`IEnumerable<>`) to `Data` property, `TextProperty` to the string property name of the item in the collection and `ValueProperty` to the property name with unique values in the collection.
### Statically declared items
```
<RadzenRadioButtonList @bind-Value=@value TValue="int" Change=@OnChange>
<Items>
<RadzenRadioButtonListItem Text="Orders" Value="1" />
<RadzenRadioButtonListItem Text="Employees" Value="2" />
<RadzenRadioButtonListItem Text="Customers" Value="3" />
</Items>
</RadzenRadioButtonList>
@code {
int value = 1;
void OnChange(int? value)
{
Console.WriteLine($"Value changed to {value}");
}
}
```
### Items populated from data
```
<RadzenRadioButtonList Data="@data" TextProperty="Name" ValueProperty="Id" @bind-Value=@value TValue="int" Change=@OnChange />
@code {
int value = 1;
IEnumerable<MyObject> data = new MyObject[] {
new MyObject(){ Id = 1 , Name = "Orders"}, new MyObject() { Id = 2 , Name = "Employees"}, new MyObject() { Id = 3 , Name = "Customers" } };
void OnChange(int? value)
{
Console.WriteLine($"Value changed to {value}");
}
}
```
### Statically declared and populated from data items
```
<RadzenRadioButtomList Data="@data" TextProperty="Name" ValueProperty="Id" @bind-Value=@value TValue="int" Change=@OnChange>
<Items>
<RadzenRadioButtonListItem Text="Static item" Value="0" />
</Items>
</RadzenRadioButtonList>
@code {
int value = 1;
IEnumerable<MyObject> data = new MyObject[] {
new MyObject(){ Id = 1 , Name = "Orders"}, new MyObject() { Id = 2 , Name = "Employees"}, new MyObject() { Id = 3 , Name = "Customers" } };
void OnChange(int? value)
{
Console.WriteLine($"Value changed to {value}");
}
}
```
### Orientation
Use Orientation property to set if RadioButtonList orientation is horizontal or vertical.
```
<RadzenRadioButtonList Orientation="Orientation.Vertical" ...
```

View File

@@ -1,18 +0,0 @@
# Rating component
This article demonstrates how to use the Rating component.
## Get and set the value
As all Radzen Blazor input components the Rating has a `Value` property which gets and sets the value of the component.
Use `@bind-Value` to get the user input.
```
<RadzenRating @bind-Value=@value Stars="10" Change=@OnChange />
@code {
int value = 3;
void OnChange(int value)
{
console.Log($"Value changed to {value}");
}
}
```

View File

@@ -1,45 +0,0 @@
# RegexValidator component
This article demonstrates how to use RadzenRegexValidator.
## Basic usage
RadzenRegexValidator checks if the user input matches the specified regular expression.
To use it perform these steps:
1. Add an input component and set its `Name`. Data-bind its value to a model property via `@bind-Value=@model.Zip`.
1. Add RadzenRegexValidator and set its `Component` property to the `Name` of the input component. Set the `Pattern` property to the regular expression you want to validate against.
> [!IMPORTANT]
> RadzenRegexValidator works only inside [RadzenTemplateForm](templateform.md).
```
<RadzenTemplateForm TItem="Registration" Data=@model>
<p>
<RadzenTextBox Name="ZIP" @bind-Value=@model.Zip />
<RadzenRegexValidator Component="ZIP" Text="ZIP code must be 5 digits" Pattern="\d{5}" />
</p>
<RadzenButton ButtonType="ButtonType.Submit" Text="Submit"></RadzenButton>
</RadzenTemplateForm>
@code {
class Model
{
public string Zip { get; set; }
}
Model model = new Model();
}
```
## Conditional validation
To make the validator conditional you can set its `Visible` property. When set to `false` the validator will not run.
## Appearance
By default RadzenRegexValidator appears next to the component it validates.
To make it appear below set its `Style` to `"display:block"`.
```
<RadzenTextBox Name="ZIP" @bind-Value=@model.Zip />
<RadzenRegexValidator Style="display:block" Component="ZIP" Text="ZIP code must be 5 digits" Pattern="\d{5}" />
```
To make it appear as a styled popup set its `Popup` property to `true` and set its CSS position to `absolute`. The validated component should have `display: block` so the validation message appears right below it.
```
<RadzenTextBox Style="display:block" Name="ZIP" @bind-Value=@model.Zip />
<RadzenRegexValidator Popup="true" Style="position:absolute" Component="ZIP" Text="ZIP code must be 5 digits" Pattern="\d{5}" />
```

View File

@@ -1,70 +0,0 @@
# RequiredValidator component
This article demonstrates how to use RadzenRequiredValidator.
## Basic usage
RadzenRequiredValidator checks if the user entered a required value.
To use it perform these steps:
1. Add an input component and set its `Name`. Data-bind its value to a model property via `@bind-Value=@model.Email`.
1. Add RadzenRequiredValidator and set its `Component` property to the `Name` of the input component.
> [!IMPORTANT]
> RadzenRequiredValidator works only inside [RadzenTemplateForm](templateform.md).
Here is a typical user registration form which checks if the user entered the same password.
```
<RadzenTemplateForm TItem="Registration" Data=@model>
<p>
<RadzenLabel Text="Email" />
<RadzenTextBox Name="Email" @bind-Value=@model.Email />
<RadzenRequiredValidator Component="Email" Text="Enter email" />
</p>
<RadzenButton ButtonType="ButtonType.Submit" Text="Submit"></RadzenButton>
</RadzenTemplateForm>
@code {
class Registration
{
public string Email { get; set; }
}
Registration model = new Registration();
}
```
## Default value
Sometimes the default property value is not `null`. Then RadzenRequiredValidator will never trigger. In such cases you need to
set the `DefaultValue` property. A common use case are numeric properties whose default value is `0`. To validate such properties
with RadzenRequiredValidator set its `DefaultValue` to `0`.
```
<RadzenTemplateForm TItem="Registration" Data=@model>
<p>
<RadzenLabel Text="Age" />
<RadzenNumeric Name="Age" @bind-Value=@model.Age />
<RadzenRequiredValidator Component="Age" Text="Age is required" DefaultValue="0" />
</p>
<RadzenButton ButtonType="ButtonType.Submit" Text="Submit"></RadzenButton>
</RadzenTemplateForm>
@code {
class Registration
{
public string Email { get; set; }
public int Age { get; set; } // Age is set to 0 by default
}
Registration model = new Registration();
}
```
## Conditional validation
To make the validator conditional you can set its `Visible` property. When set to `false` the validator will not run.
## Appearance
By default RadzenRequiredValidator appears next to the component it validates.
To make it appear below set its `Style` to `"display:block"`.
```
<RadzenTextBox Name="Email" @bind-Value=@model.Email />
<RadzenRequiredValidator Component="Email" Text="Enter email" Style="display:block" />
```
To make it appear as a styled popup set its `Popup` property to `true` and set its CSS position to `absolute`. The validated component should have `display: block` so the validation message appears right below it.
```
<RadzenTextBox Name="Email" @bind-Value=@model.Email Style="display:block" />
<RadzenRequiredValidator Component="Email" Text="Enter email" Style="position:absolute" Popup="true" />
```

View File

@@ -1,97 +0,0 @@
# Scheduler component
This article demonstrates how to use RadzenScheduler.
## Basic usage
RadzenScheduler can display appointments in three ways (a.k.a. views) - day view, week view and month view.
The following properties configure the scheduler.
- Data - specifies the data source which contains the appointments - a collection of objects.
- StartProperty - the name of the property which contains the start date of an appointment. The property should be of `DateTime` type.
- EndProperty - the name of the property which contains the end date of an appointment. The property should be of `DateTime` type.
- TextProperty - the name of the property which contains the text of an appointment - this is the message that the scheduler will display. The property should be of `String` type.
Here is a minimal example.
```
<RadzenScheduler Data="@data" TItem="DataItem" StartProperty="Start" EndProperty="End" TextProperty="Text">
<RadzenMonthView />
</RadzenScheduler>
@code {
class DataItem
{
public DateTime Start { get; set; }
public DateTime End { get; set; }
public string Text { get; set; }
}
DataItem[] data = new DataItem[]
{
new DataItem
{
Start = DateTime.Today,
End = DateTime.Today.AddDays(1),
Text = "Birthday"
},
};
}
```
The `RadzenMonthView` tag is used to specify that the scheduler will display appointments in month view. The `Data` property specifies the data source. The scheduler will render an appointment for every `DataItem` instance from the `data` array and will display its `Text` property.
## CRUD
To support adding and editing of appointments you can handle the `SlotSelect` and `AppointmentSelect` events.
Check the [online example](/scheduler) for a complete implementation.
> [!IMPORTANT]
> To make the scheduler display the latest changes you should do one of the following:
> - invoke the `Reload()` method of the scheduler
> - Reassign its `Data` property to a new `IEnumerable<T>` instance.
## Customize appointment appearance
To customize the appointment appearance use the `Template` setting of RadzenScheduler.
```
<RadzenScheduler Data="@data" TItem="DataItem" StartProperty="Start" EndProperty="End" TextProperty="Text">
<Template Context="data">
<strong>@data.Text</strong>
</Template>
<ChildContent>
<RadzenMonthView />
</ChildContent>
</RadzenScheduler>
```
The template context is the data item (of type `TItem`).
## Views
To add more views simply list them as child tags within RadzenScheduler.
```
<RadzenScheduler Data="@data" TItem="DataItem" StartProperty="Start" EndProperty="End" TextProperty="Text">
<RadzenDayView />
<RadzenWeekView />
<RadzenMonthView />
</RadzenScheduler>
```
To set the initially selected view use the `SelectedIndex` property. By default RadzenScheduler displays the first view.
```
<RadzenScheduler SelectedIndex="1" Data="@data" TItem="DataItem" StartProperty="Start" EndProperty="End" TextProperty="Text">
<RadzenDayView />
<RadzenWeekView />
<RadzenMonthView />
</RadzenScheduler>
```
## LoadData event
If you set the Data property of the scheduler to `IQueryable<T>` it will use expression trees that
Entity Framework core will automatically convert to SQL. This will ensure that only the appointments
required for the time period displayed by the current view are fetched from the database.
For custom implementations you can use the `LoadData` event. It provides the `Start` and `End` of the current period.
```
<RadzenScheduler LoadData="@OnLoadData" Data="@data" TItem="DataItem" StartProperty="Start" EndProperty="End" TextProperty="Text">
<RadzenMonthView />
</RadzenScheduler>
@code {
IEnumerable<DataItem> data;
async Task OnLoadData(SchedulerLoadDataEventArgs args)
{
// Get the appointments for between the Start and End
data = await MyAppointmentService.GetData(args.Start, args.End);
}
}
```

View File

@@ -1,85 +0,0 @@
# SelectBar component
This article demonstrates how to use the SelectBar component.
## Get and set the value
As all Radzen Blazor input components the SelectBar has a `Value` property which gets and sets the value of the component.
Use `@bind-Value` to get the user input. The `TValue` property should be set to the `Value` property type.
## Data-binding
To display data in SelectBar component you can statically declare items in the markup and/or set collection of items (`IEnumerable<>`) to `Data` property, `TextProperty` to the string property name of the item in the collection and `ValueProperty` to the property name with unique values in the collection.
### Statically declared items with single selection
```
<RadzenSelectBar @bind-Value=@singleValue TValue="bool" Change=@OnChange>
<Items>
<RadzenSelectBarItem Text="On" Value="true" />
<RadzenSelectBarItem Text="Off" Value="false" />
</Items>
</RadzenSelectBar>
@code {
bool singleValue = false;
void OnChange(object value)
{
var str = value is IEnumerable<int> ? string.Join(", ", (IEnumerable<int>)value) : value;
Console.WriteLine($"Value changed to {str}");
}
}
```
### Statically declared items with multiple selection
```
<RadzenSelectBar @bind-Value=@values TValue="IEnumerable<int>" Multiple="true" Change=@OnChange>
<Items>
<RadzenSelectBarItem Text="Orders" Value="1" />
<RadzenSelectBarItem Text="Employees" Value="2" />
<RadzenSelectBarItem Text="Customers" Value="3" />
</Items>
</RadzenSelectBar>
@code {
IEnumerable<int> values = new int[] { 1, 2 };
void OnChange(object value)
{
var str = value is IEnumerable<int> ? string.Join(", ", (IEnumerable<int>)value) : value;
Console.WriteLine($"Value changed to {str}");
}
}
```
### Items populated from data
```
<RadzenSelectBar @bind-Value=@values TValue="IEnumerable<int>" Multiple="true" Change=@OnChange Data="@data" TextProperty="Name" ValueProperty="Id" />
@code {
IEnumerable<int> values = new int[] { 1 };
IEnumerable<MyObject> data = new MyObject[] {
new MyObject(){ Id = 1 , Name = "Orders"}, new MyObject() { Id = 2 , Name = "Employees"}, new MyObject() { Id = 3 , Name = "Customers" } };
void OnChange(IEnumerable<int> value)
{
Console.WriteLine($"Value changed to {string.Join(", ", value)}");
}
}
```
### Statically declared and populated from data items
```
<RadzenSelectBar @bind-Value=@values Data="@data" TextProperty="Name" ValueProperty="Id" TValue="IEnumerable<int>" Multiple="true" Change=@OnChange>
<Items>
<RadzenSelectBarItem Text="Static item" Value="0" />
</Items>
</RadzenSelectBar>
@code {
IEnumerable<int> values = new int[] { 1, 2 };
IEnumerable<MyObject> data = new MyObject[] {
new MyObject(){ Id = 1 , Name = "Orders"}, new MyObject() { Id = 2 , Name = "Employees"}, new MyObject() { Id = 3 , Name = "Customers" } };
void OnChange(object value)
{
var str = value is IEnumerable<int> ? string.Join(", ", (IEnumerable<int>)value) : value;
Console.WriteLine($"Value changed to {str}");
}
}
```

View File

@@ -1,64 +0,0 @@
# Slider component
This article demonstrates how to use the Slider component.
## Get and set the value
As all Radzen Blazor input components the Slider has a `Value` property which gets and sets the value of the component.
Use `@bind-Value` to get the user input.
```
<RadzenSlider @bind-Value=@value TValue="int" Min="0" Max="100" Change=@OnChange />
@code {
int value = 67;
void OnChange(dynamic value)
{
var str = value is IEnumerable ? string.Join(", ", value) : value;
console.Log($"{name} value changed to {str}");
}
}
```
## Slider from -100 to 100
```
<RadzenSlider @bind-Value=@value TValue="int" Min="-100" Max="100" Change=@OnChange />
@code {
int value = 67;
void OnChange(dynamic value)
{
var str = value is IEnumerable ? string.Join(", ", value) : value;
console.Log($"{name} value changed to {str}");
}
}
```
## Slider with Step 10
```
<RadzenSlider @bind-Value=@value TValue="int" Step="10" />
@code {
void OnChange(dynamic value)
{
var str = value is IEnumerable ? string.Join(", ", value) : value;
console.Log($"{name} value changed to {str}");
}
}
```
## Range Slider
```
<RadzenSlider Range="true" @bind-Value=@values TValue="IEnumerable<int>" />
@code {
IEnumerable<int> values = new int[] { 14, 78 };
void OnChange(dynamic value)
{
var str = value is IEnumerable ? string.Join(", ", value) : value;
console.Log($"{name} value changed to {str}");
}
}
```

View File

@@ -1,58 +0,0 @@
# SplitButton component
This article demonstrates how to use the SplitButton component.
```
<RadzenSplitButton Click=@OnClick Text="SplitButton" Icon="account_circle">
<ChildContent>
<RadzenSplitButtonItem Text="Item1" Value="1" Icon="account_box" />
<RadzenSplitButtonItem Text="Item2" Value="2" Icon="account_balance_wallet" />
</ChildContent>
</RadzenSplitButton>
@code {
void OnClick(RadzenSplitButtonItem item)
{
if(item != null)
{
Console.WriteLine($"Item with value {item.Value} clicked");
}
else
{
Console.WriteLine($"Button clicked");
}
}
}
```
## Disabled states
You can disable the whole RadzenSplitButton or only some items of it.
```
<RadzenSplitButton Disabled="true" Text="SplitButton">
<ChildContent>
<RadzenSplitButtonItem Text="Item1" Value="1" />
<RadzenSplitButtonItem Text="Item2" Value="2" />
</ChildContent>
</RadzenSplitButton>
```
```
<RadzenSplitButton Text="SplitButton">
<ChildContent>
<RadzenSplitButtonItem Text="Item1" Value="1" />
<RadzenSplitButtonItem Text="Disabled Item2" Value="2" Disabled="true" />
</ChildContent>
</RadzenSplitButton>
```
## Always open popup with items
Sometimes you wish do not have default click handler on the main button rather show all available items.
```
<RadzenSplitButton AlwaysOpenPopup=true Text="SplitButton">
<ChildContent>
<RadzenSplitButtonItem Text="Item1" Value="1" />
<RadzenSplitButtonItem Text="Item2" Value="2" />
</ChildContent>
</RadzenSplitButton>
```

View File

@@ -1,108 +0,0 @@
# Splitter component
This article demonstrates how to use Splitter.
```
<RadzenSplitter Orientation="Orientation.Vertical" Collapse=@OnCollapse Expand=@OnExpand style="height: 400px; border: 1px solid #777777;">
<RadzenSplitterPane Size="100px">
<RadzenSplitter Collapse=@OnCollapse Expand=@OnExpand>
<RadzenSplitterPane Size="50%" Min="30px" Max="70%">
Pane A1
<div style="font-size: 10px;">
50% Min 30px Max 70%
</div>
</RadzenSplitterPane>
<RadzenSplitterPane>
Pane A2
</RadzenSplitterPane>
</RadzenSplitter>
</RadzenSplitterPane>
<RadzenSplitterPane Size="100px">
<RadzenSplitter Collapse=@OnCollapse Expand=@OnExpand Resize=@OnResize>
<RadzenSplitterPane Size="50px" Min="30px">
Pane B1
<div style="font-size: 10px;">
Size 50px Min 30px
</div>
</RadzenSplitterPane>
<RadzenSplitterPane>
Pane B2
</RadzenSplitterPane>
<RadzenSplitterPane Resizable="false">
Pane B3
<div style="font-size: 10px;">
not resizable
</div>
</RadzenSplitterPane>
<RadzenSplitterPane Min="10%">
Pane B4
<div style="font-size: 10px;">
Min 10%
</div>
</RadzenSplitterPane>
<RadzenSplitterPane Collapsible="false">
Pane B5
<div style="font-size: 10px;">
not collapsible
</div>
</RadzenSplitterPane>
<RadzenSplitterPane Visible="false">
Pane B6
</RadzenSplitterPane>
<RadzenSplitterPane Resizable="false">
Pane B7
<div style="font-size: 10px;">
not resizable
</div>
</RadzenSplitterPane>
<RadzenSplitterPane>
Pane B8
</RadzenSplitterPane>
</RadzenSplitter>
</RadzenSplitterPane>
<RadzenSplitterPane>
<RadzenSplitter Collapse=@OnCollapseDisabled Resize=@OnResizeDisabled>
<RadzenSplitterPane>
Pane C1
<div style="font-size: 10px;">
collapse and resize programmatically disabled
</div>
</RadzenSplitterPane>
<RadzenSplitterPane>
Pane C2
<div style="font-size: 10px;">
collapse and resize programmatically disabled
</div>
</RadzenSplitterPane>
</RadzenSplitter>
</RadzenSplitterPane>
</RadzenSplitter>
@code {
void OnCollapse(RadzenSplitterEventArgs args)
{
Console.WriteLine($"Pane {args.PaneIndex} Collapse");
}
void OnExpand(RadzenSplitterEventArgs args)
{
Console.WriteLine($"Pane {args.PaneIndex} Expand");
}
void OnResize(RadzenSplitterResizeEventArgs args)
{
Console.WriteLine($"Pane {args.PaneIndex} Resize (New size {args.NewSize})");
}
void OnCollapseDisabled(RadzenSplitterEventArgs args)
{
args.Cancel = true;
Console.WriteLine($"Pane {args.PaneIndex} Collapse programmatically disabled");
}
void OnResizeDisabled(RadzenSplitterResizeEventArgs args)
{
args.Cancel = true;
Console.WriteLine($"Pane {args.PaneIndex} Resize (New size {args.NewSize}) programmatically disabled");
}
}
```

View File

@@ -1,27 +0,0 @@
# Steps component
This article demonstrates how to use Steps.
```
<RadzenSteps @bind-SelectedIndex=@selectedIndex Change=@OnChange>
<Steps>
<RadzenStepsItem Text="Customers">
Customers
</RadzenStepsItem>
<RadzenStepsItem Text="Orders" Disabled="@(selectedCustomers == null || selectedCustomers != null && !selectedCustomers.Any())">
Orders
</RadzenStepsItem>
<RadzenStepsItem Text="Order Details" Disabled="@(selectedOrders == null || selectedOrders != null && !selectedOrders.Any())">
Order Details
</RadzenStepsItem>
</Steps>
</RadzenSteps>
@code {
int selectedIndex = 0;
void OnChange(int index)
{
console.Log($"Step with index {index} was selected.");
}
}
```

View File

@@ -1,18 +0,0 @@
# Switch component
This article demonstrates how to use the Switch component.
## Get and set the value
As all Radzen Blazor input components the Switch has a `Value` property which gets and sets the value of the component.
Use `@bind-Value` to get the user input.
```
<RadzenSwitch @bind-Value=@value Change=@OnChange />
@code {
bool value;
void OnChange(bool value)
{
Console.WriteLine($"Value changed to {value}");
}
}
```

Some files were not shown because too many files have changed in this diff Show More