If you set args.IsCancelled=true in any CUD event handler, the loading sign will never go away.
---
ADMIN EDIT
If you don't need to cancel the event (e.g., because remote validation or data operation failed), you should avoid cancelling it - its purpose is to keep the grid in the current mode (edit/insert) when the operation fails so the user does not lose data.
That said, the loading sing should disappear in thsoe cases too, and a workaround is to disable it by setting the EnableLoaderContainer="false" parameter of the grid.
---
Using the keyboard to save items works inconsistently. When editing an item, hitting enter seems to save the change as expected. When inserting an item, however, the item is lost.
---
ADMIN EDIT
Tthe grid calls the OnUpdate handler again, not OnCreate which results in data loss - the newly inserted item is unlikely to match existing data and so it appears to be lost.
Workaround - call the OnCreate handler yourself when the ID of the record is the default for its type - for example, zero for an integer. This indicates a newly inserted record in the grid.
<TelerikGrid Data=@MyData EditMode="@GridEditMode.Inline" Pageable="true" Height="500px" Navigable="true"
OnUpdate="@UpdateHandler" OnDelete="@DeleteHandler" OnCreate="@CreateHandler" OnCancel="@CancelHandler">
<GridToolBar>
<GridCommandButton Command="Add" Icon="add">Add Employee</GridCommandButton>
</GridToolBar>
<GridColumns>
<GridColumn Field=@nameof(SampleData.ID) Title="ID" Editable="false" />
<GridColumn Field=@nameof(SampleData.Name) Title="Name" />
<GridCommandColumn>
<GridCommandButton Command="Save" Icon="save" ShowInEdit="true">Update</GridCommandButton>
<GridCommandButton Command="Edit" Icon="edit">Edit</GridCommandButton>
<GridCommandButton Command="Delete" Icon="delete">Delete</GridCommandButton>
<GridCommandButton Command="Cancel" Icon="cancel" ShowInEdit="true">Cancel</GridCommandButton>
</GridCommandColumn>
</GridColumns>
</TelerikGrid>
@code {
async Task UpdateHandler(GridCommandEventArgs args)
{
SampleData item = (SampleData)args.Item;
if (item.ID == 0)
{
await CreateHandler(args);
}
else
{
// perform actual data source operations here through your service
await MyService.Update(item);
// update the local view-model data with the service data
await GetGridData();
Console.WriteLine("Update event is fired.");
}
}
async Task DeleteHandler(GridCommandEventArgs args)
{
SampleData item = (SampleData)args.Item;
// perform actual data source operation here through your service
await MyService.Delete(item);
// update the local view-model data with the service data
await GetGridData();
Console.WriteLine("Delete event is fired.");
}
async Task CreateHandler(GridCommandEventArgs args)
{
SampleData item = (SampleData)args.Item;
// perform actual data source operation here through your service
await MyService.Create(item);
// update the local view-model data with the service data
await GetGridData();
Console.WriteLine("Create event is fired.");
}
async Task CancelHandler(GridCommandEventArgs args)
{
SampleData item = (SampleData)args.Item;
// if necessary, perform actual data source operation here through your service
Console.WriteLine("Cancel event is fired.");
}
// in a real case, keep the models in dedicated locations, this is just an easy to copy and see example
public class SampleData
{
public int ID { get; set; }
public string Name { get; set; }
}
public List<SampleData> MyData { get; set; }
async Task GetGridData()
{
MyData = await MyService.Read();
}
protected override async Task OnInitializedAsync()
{
await GetGridData();
}
// the following static class mimics an actual data service that handles the actual data source
// replace it with your actual service through the DI, this only mimics how the API can look like and works for this standalone page
public static class MyService
{
private static List<SampleData> _data { get; set; } = new List<SampleData>();
public static async Task Create(SampleData itemToInsert)
{
itemToInsert.ID = _data.Count + 1;
_data.Insert(0, itemToInsert);
}
public static async Task<List<SampleData>> Read()
{
if (_data.Count < 1)
{
for (int i = 1; i < 50; i++)
{
_data.Add(new SampleData()
{
ID = i,
Name = "Name " + i.ToString()
});
}
}
return await Task.FromResult(_data);
}
public static async Task Update(SampleData itemToUpdate)
{
var index = _data.FindIndex(i => i.ID == itemToUpdate.ID);
if (index != -1)
{
_data[index] = itemToUpdate;
}
}
public static async Task Delete(SampleData itemToDelete)
{
_data.Remove(itemToDelete);
}
}
}
---
Our Site supports multiple themes that we have built using the SASS Theme Builder. For all Telerik Components we have used so far the theme changes on them as expected when using the example found here (Change Theme at Runtime). The problem seems to be the chart component will not adhere to the newly applied theme after its initial load. Seems like this is because it is shown as an SVG with hardcoded attributes on the element. Is there a workaround for this (other than reloading the components entirely)?
Before & After Theme Change:
If the "Navigable" parameter of the Grid is set to false (its default state) and the EditMode is PopUp, there is no focus on the first input in Add/Edit mode.
Add checkbox support at the node level. Similar to...
https://www.telerik.com/kendo-angular-ui/components/treeview/checkboxes/
1. Create tree model from class:
public class TreeNodeViewModel
{
public string NodeName { get; set; }
public IEnumerable<TreeNodeViewModel> Children { get; set; }
public bool Expanded { get; set; }
public string Color { get; set; }
public string IconClass { get; set; }
}
2. Pass this tree for rendering to the component "TelerikTreeView".
3. An error comes out:
2020-12-03T09:44:15.312Z] Error: System.AggregateException: One or more errors occurred. (Object reference not set to an instance of an object.)
---> System.NullReferenceException: Object reference not set to an instance of an object.
at Telerik.Blazor.Data.TelerikTreeViewDataSource.GetFlatItems(IEnumerable`1 tree, List`1 result)
at Telerik.Blazor.Data.TelerikTreeViewDataSource.GetFlatItems(IEnumerable`1 tree, List`1 result)
at Telerik.Blazor.Data.TelerikTreeViewDataSource.GetFlatItems(IEnumerable`1 tree, List`1 result)
at Telerik.Blazor.Data.TelerikTreeViewDataSource.GetFlatItems(IEnumerable`1 tree, List`1 result)
at Telerik.Blazor.Data.TelerikTreeViewDataSource.FlattenTree()
at Telerik.Blazor.Data.TelerikTreeViewDataSource.InitData(IEnumerable`1 sourceData)
at Telerik.Blazor.Data.TelerikTreeViewDataSource.ProcessData(IEnumerable data)
at Telerik.Blazor.Components.TelerikTreeView.ProcessDataInternal()
at Telerik.Blazor.Components.Common.DataBoundComponent`1.ProcessDataAsync()
at Telerik.Blazor.Components.TelerikTreeView.OnAfterRenderAsync(Boolean firstRender)
--- End of inner exception stack trace ---
Note: This problem is due to the fact that there are no children in the last node of the tree and IEnumerable Children == NULL. Method "GetFlatItems" in version 2.18.0 it had a NULL check, in version 2.20.0 it is not.
---
ADMIN EDIT
When the component calculates the size of the chunks it doesn't seem to use invariant culture so when the decimal separator is a comma `,` it puts that comma in the CSS rule, which the browser can't parse and the chunks have wrong sizes which makes them invisible.
Reproducible plus CSS workaround
<h4>Default</h4>
<TelerikChunkProgressBar Value="1" Max="3" ChunkCount="3"></TelerikChunkProgressBar><br /><br />
<TelerikChunkProgressBar Value="3" Max="3" ChunkCount="3"></TelerikChunkProgressBar><br /><br />
<TelerikChunkProgressBar Value="1" Max="7" ChunkCount="7"></TelerikChunkProgressBar><br /><br />
<TelerikChunkProgressBar Value="4" Max="7" ChunkCount="7"></TelerikChunkProgressBar><br /><br />
<TelerikChunkProgressBar Value="7" Max="7" ChunkCount="7"></TelerikChunkProgressBar>
<h4>With Workaround</h4>
<style>
.three-chunks-workaround li {
width: 33.333% !important;
}
.seven-chunks-workaround li {
width: 14.285% !important;
}
</style>
<TelerikChunkProgressBar Class="three-chunks-workaround" Value="1" Max="3" ChunkCount="3"></TelerikChunkProgressBar><br /><br />
<TelerikChunkProgressBar Class="three-chunks-workaround" Value="3" Max="3" ChunkCount="3"></TelerikChunkProgressBar><br /><br />
<TelerikChunkProgressBar Class="seven-chunks-workaround" Value="1" Max="7" ChunkCount="7"></TelerikChunkProgressBar><br /><br />
<TelerikChunkProgressBar Class="seven-chunks-workaround" Value="4" Max="7" ChunkCount="7"></TelerikChunkProgressBar><br /><br />
<TelerikChunkProgressBar Class="seven-chunks-workaround" Value="7" Max="7" ChunkCount="7"></TelerikChunkProgressBar>
@code{
protected override void OnInitialized()
{
var culture = new System.Globalization.CultureInfo("sv-SE");
System.Globalization.CultureInfo.DefaultThreadCurrentCulture = culture;
System.Globalization.CultureInfo.DefaultThreadCurrentUICulture = culture;
base.OnInitialized();
}
}
When you go backwards in the listview paging it exhibits two issues:
- some (almost random) elements remain after the paged elements
- if, as a first action, you go from the last to the first page through the pager buttons, an exception is thrown - Unhandled exception rendering component: Event 112 is already tracked
I'm working on blazor server side application.
After update Telerik.UI.for.Blazor from 2.1 to 2.5 (before I
updated .net core from 3.0 to 3.1) it shows following error:
InvalidOperationException: The current thread is not associated
with the Dispatcher. Use InvokeAsync() to switch execution to the Dispatcher
when triggering rendering or component state.
I investigated that it's cause by Telerik window.
The error occurs when window is on start page or when the
page is refreshed.
Below code for Index.razor which cause the error:
@page "/"
<
TelerikWindow
@
bind-Visible
=
"@WindowIsVisible"
>
<
WindowTitle
>
<
strong
>The Title</
strong
>
</
WindowTitle
>
<
WindowContent
>
This is my window <
strong
>popup</
strong
> content.
</
WindowContent
>
<
WindowActions
>
<
WindowAction
Name
=
"Minimize"
></
WindowAction
>
<
WindowAction
Name
=
"Maximize"
></
WindowAction
>
<
WindowAction
Name
=
"Close"
></
WindowAction
>
</
WindowActions
>
</
TelerikWindow
>
<
TelerikButton
OnClick="@( () => WindowIsVisible = !WindowIsVisible )">Toggle window</
TelerikButton
>
@code {
bool WindowIsVisible { get; set; } = false;
}
In many cases users need to be able to specify a number which is easily visualized using a horizontal slider.
This allows the user to easily move the point to their desired location.
It can be helpful to allow this to also be constrained using a forced range selection.
When the Label parameter of the TelerikMaskedTextBox is not defined, the Width is applied to the input of the component. However, it should be applied to the span holding the component.
====================================
ADMIN EDIT
A couple of workarounds:
=====================================