Hi, I try tu use the new Date/TimeOnly types of .Net6 and they are not supported by the Telerik components (you cannot bind them to these types). I tested it on the 2.30.0 version you just released.
It works fine with the Blazor Components (InputDate, input type="time"...) but it is not a practical solution for component like TelerikGrid (it would mean templating everything, breaking the inline validation etc.) or TelerikScheduler/Gantt (I would like to use a DateOnly for its Date property for example, and ideally its model could be a DateOnly and 2 TimeOnly instead of 2 DateTime but that's less important).
Do you have an ETA for their support or a workaround?
Also, is there documentation about the limitations of your .Net6 support so I don't have other bad surprises?
Hi I have made a utility class for helping with state management
<TelerikButton OnClick="@_gridStateManager.SaveState" Icon="download">Save State</TelerikButton>
<TelerikButton OnClick="@_gridStateManager.LoadState" Icon="upload">Load State</TelerikButton>
<TelerikButton OnClick="@_gridStateManager.ResetState" Icon="reset">Reset State</TelerikButton>
In the code behind file
protected override async Task OnInitializedAsync()
{
_gridStateManager = new GridStateManager<PortfolioListItem>(LocalStorage, PortfolioListGrid, GetDefaultGridState);
}
The problem is that the GridStateManger gets a null reference to the grid.
I know that the @ref is only safe to get in OnAfterRender / Async. How can I initialize the GridStateManager with the @ref set and also make it possible for the grid to call :
OnStateInit="@((GridStateEventArgs<PortfolioListItem> args) => _gridStateManager.OnStateInitHandler(args))">
In a safe way?
This is the code for my GridStateManager
using System;
using System.Threading.Tasks;
using Blazored.LocalStorage;
using Telerik.Blazor.Components;
namespace Argus.Client;
public class GridStateManager<T> where T : class
{
private readonly ILocalStorageService _localStorage;
private readonly TelerikGrid<T> _grid;
private readonly Func<GridState<T>> _getDefaultGridState;
private readonly string _stateStorageKey;
public GridStateManager(
ILocalStorageService localStorage,
TelerikGrid<T> grid,
Func<GridState<T>> getDefaultGridState)
{
_localStorage = localStorage;
_grid = grid;
_getDefaultGridState = getDefaultGridState;
_stateStorageKey = $"GridStateFor{nameof(T)}";
}
public async Task OnStateInitHandler(GridStateEventArgs<T> args)
{
try
{
var storageState = await _localStorage.GetItemAsync<GridState<T>>(_stateStorageKey);
if (storageState != null)
args.GridState = storageState;
if (storageState == null && _getDefaultGridState != null)
args.GridState = _getDefaultGridState();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
public async Task SaveState()
{
var gridState = _grid.GetState();
await _localStorage.SetItemAsync(_stateStorageKey, gridState);
}
public async Task LoadState()
{
GridState<T> storedState = await _localStorage.GetItemAsync<GridState<T>>(_stateStorageKey);
if (storedState != null)
{
await _grid.SetState(storedState);
}
}
public async void ResetState()
{
if (_getDefaultGridState != null)
{
await _grid.SetState(_getDefaultGridState());
}
await _localStorage.RemoveItemAsync(_stateStorageKey);
}
}
If I could get the grid reference in the OnStateInit EventCallBack then I would have solved the problem
OnStateInit="@((GridStateEventArgs<PortfolioListItem> args) => _gridStateManager.OnStateInitHandler(args, @gridRef))">
I then tried to create the GridStateManger in the OnStateInit call from the grid. But I still don't have a valid ref to the grid, why?
OnStateInit="@((GridStateEventArgs<PortfolioListItem> args) => InitGridStateManager(args))">
private async Task InitGridStateManager(GridStateEventArgs<PortfolioListItem> args)
{
_gridStateManager = new GridStateManager<PortfolioListItem>(LocalStorage, PortfolioListGrid, GetDefaultGridState);
await _gridStateManager.OnStateInitHandler(args);
}
Currently I have nine service classes in this, my first Blazor app (.Net 6). Each service contains the usual async Tasks required for CRUD, eg GetStudyFees, CreateStudyFee, UpdateStudyFee. So, since this is a data intensive intranet app, which is I believe considered just the thing Blazor Server is good for, in each service I need a connection string ( I'm using Dapper), and I need the current user name, since we want to save CreatedBy and ModifiedBy.
This is how I've set this up for one service:
private readonly string _conn;
private readonly AuthenticationStateProvider _auth;
public StudyFeeService(IConfiguration config, AuthenticationStateProvider auth)
{
_conn = config.GetConnectionString("PharmCTConn");
_auth = auth;
}
public async Task<string> GetUser()
{
var authState = await _auth.GetAuthenticationStateAsync();
var user = authState.User;
return user.Identity.Name;
}
public async Task<bool> CreateStudyFee(StudyFeeViewModel studyFee)
{
var parameters = new DynamicParameters();
studyFee.CreatedBy = await GetUser();
parameters.AddDynamicParams(new
{
studyFee.HREC,
studyFee.Fee,
studyFee.CreatedBy
});
using (var conn = new SqlConnection(_conn))
{
string query = @"insert into dbo.StudyFee (HREC, Fee, CreatedBy)
values (@HREC, @Fee, @CreatedBy)";
await conn.ExecuteAsync(query, parameters, commandType: CommandType.Text);
}
return true;
}
Hi I have added the LoadContainer to the MainLayout. Now I can inject it like this
[CascadingParameter] protected ShowProgressIndicator Progress { get; set; }
MainLayout.razor
<TelerikRootComponent>
<NavMenu/>
<div class="page">
<TelerikNotification @ref="@Notification.Instance"
HorizontalPosition="@NotificationHorizontalPosition.Right"
VerticalPosition="@NotificationVerticalPosition.Top"
Class="bi-notification">
</TelerikNotification>
<TelerikLoaderContainer Visible="@ProgressIndicator.Visible" Text="Working on it .." Size="@LoaderSize.Large"/>
<CascadingValue IsFixed="true" Value="@Notification">
<CascadingValue Value="@ProgressIndicator">
@Body
</CascadingValue>
</CascadingValue>
</div>
</TelerikRootComponent>
@code
{
Notification Notification { get; } = new();
ShowProgressIndicator ProgressIndicator { get; } = new();
}
What I can't get to work is setting the loading text on the LoadContainer. It's always using the default text "Loading ..."
Show/Hide works fine.
Progress.Visible = true;
public class ShowProgressIndicator
{
public TelerikLoaderContainer LoaderContainer { get; set; }
public bool Visible { get; set; }
public string Text { get; set; } = "Working on it ..";
// public void Show()
// {
// Text = "Working on it ..";
// Visible = true;
// }
//
// public void Hide()
// {
// Visible = false;
// }
}
I feel a bit silly not being able to find the "right" solution to this, but here it goes...
I see the Blazor Card demos has an Expandable demo. I want to do something a lot like this but I will have many cards, each one of them should be able to expand it's own "sub-content" at will. The demo shows a single button tied to a single TelerikAnimationContainer. What is the best solution to have 1-n cards, each with their own expandable content that slides out? (mine will slide out to the right, but I don't know that that matters).
Thanks,
Justin
Telerik UI for Blazor 2.29.0
<TelerikButton>Hello</TelerikButton>
generates a button with "HELLO" as the text...all uppercase. Looks like the .k-button css class has "text-transform: uppercase" on it. Is this due to the Material theme? I am using Telerik.UI.for.Blazor.2.29.0, which is the latest as of this writing.
I would like the casing of the text to be how I decide.
Thanks,
Justin
I want to ask if there are classes for adding hover and selected styles for the Card?
Would also like the card to act as one big button.
Hello,
I have a telerik menu, with a submenu in it. How do I stop the primary menu from closing, when dragging the mouse out of the submenu in the "wrong" position? Or is it possible to align the submenu to the left of the primary menu?
Its a bit hard some times to reach all menu items below the submenu trigger, when the primary menu keeps closing.
Video:
https://youtu.be/oFT09e17gyk
Thanks
Regards,
Nikolas
Hi,
how can I cancel the edit mode programmatically in Inline edit mode?