I'm trying to make the Editor a bit restricted for my users on specific pages. I have the following requirements:
Is it possible to lock it down?
Users would like any row selected not be filtered out of display.
new FilterDescriptor(nameof(Selected), FilterOperator.IsEqual, true)?
I do NOT wish to expose my database structures to front-end clients of my API. I use flattened Data Transfer Objects (DTO) to communicate between client and server. So, I want to use the DataRequest pieces to generate my own queries against the database to retrieve the data, I see no harm in using Data Transfer Objects (DTO) in returning a DataResponse object.
That is way more manual than your code samples or documentation shows.
Can you point me to information about parsing filters, sort orders, paging, no grouping (thankfully). I'll take it from there.
Oh, is there a decoupled control for building filters that could be applied to a grid? It seems the only two options are Menu or Row. It would seem a decoupled filter control would be terrific for saving a filter configuration as well.
The Telerik.DataSource nuget package has been updated to major version 2 with a dependency on netstandard 2.1. This causes issues for older services that are still using the full .net framework. For example, we are moving to a microservice architecture, where microservices are targeting .net core 3.1+, but the monolith the functionality is being cut out of is still using .net framework (and will use it until it dies a horrible fiery death). The communication between the microservices and monolith is based on contract assemblies, that have to target netstandard 2.0 for compatibility. Now, one of these microservices would like to expose a query API for a backoffice UI microservice using the Telerik.DataSource DataSourceRequest/DataEnvelope contract for convenient binding to Telerik widgets. The contract assembly for this communication is however also used by the old monolith to cover functionality not yet cut out to modern microservices.
Now, to the question. Is there in the works (or in the stars) a separation of the Telerik.DataSource actual contract package (the aforementioned DataSourceRequest "DTO" structure, targeting netstandard 2.0) and the implementation package (targeting netstandard 2.1)?. I've played around a bit with the source code and it looks feasible from my point of view, just not sure it would be worth the effort on your end. I do imagine though that more customers will run into this issue when migrating? I would be glad to help (with a pull request maybe) if you are interested and think that this would be worthwhile (I do realise this would be a breaking change)...
I am testing a chart with bar lines but the horizontal legend at the bottom all the numbers collapse with the others
It also happens in other charts where so many numbers or dates that are not legible, is there any workaround to avoid this and reduce the number of numbers/intervals?
I am trying to use Telerik Blazor's MediaQuery at the base page. That page, for me is, MainLayout.razor
.
First, I separated the code-behind for the MainLayout
and had to introduce a base class for my properties as MainLayout
already inherits LayoutComponentBase
:
MainLayout.razor
@using DA.BrrMs.Portal.Blazor.Helpers
@inherits MainLayoutModel
@layout TelerikLayout
<TelerikMediaQuery Media="@WindowBreakPoints.ExtraSmall" OnChange="@(matches => IsExtraSmall = matches )"/>
<TelerikMediaQuery Media="@WindowBreakPoints.Small" OnChange="@(matches => IsSmall = matches )"/>
<TelerikMediaQuery Media="@WindowBreakPoints.Medium" OnChange="@(matches => IsMedium = matches )"/>
<TelerikMediaQuery Media="@WindowBreakPoints.Large" OnChange="@(matches => IsLarge = matches )"/>
<TelerikMediaQuery Media="@WindowBreakPoints.ExtraLarge" OnChange="@(matches => IsExtraLarge = matches )"/>
<Header @bind-StateCssClass="@NavMenuCssClass"></Header>
<div class="main">
<div class="sidebar @NavMenuCssClass">
<NavMenu />
</div>
<div class="container-fluid px-2">
@Body
</div>
</div>
MainLayout.razor.cs
using DA.BrrMs.Portal.Blazor.Base;
namespace DA.BrrMs.Portal.Blazor.Shared
{
public class MainLayoutModel : BaseLayout
{
protected string NavMenuCssClass { get; set; }
}
}
BaseLayout.cs
using Microsoft.AspNetCore.Components;
namespace DA.BrrMs.Portal.Blazor.Base
{
public class BaseLayout : LayoutComponentBase
{
protected bool IsExtraSmall { get; set; }
protected bool IsSmall { get; set; }
protected bool IsMedium { get; set; }
protected bool IsLarge { get; set; }
protected bool IsExtraLarge { get; set; }
}
}
With this done, at very late hours, I realized there is no code level link between a MainLayout
and any other page and I cannot access the IsSmall
property in my dashboard page. I need to change the layout itself is screen is small or less for my mobile clients and that's another reason for me doing this at MainLayout level
Any proper way to accomplish this?
Dears ,
Because of some reason , I need to Customer Telerik Blazor Componet into Custome Componet and then Render it in Dynamic Ways ,
Like This .
FabCombobox.razor (Componet)
@typeparam T
@typeparam TResource
<div class="row"><label class="col-md-2">@Label</label><div class="col-md-5"><TelerikComboBox Value="@ResultValue" Data="@Resource" Placeholder="@Placeholder" Filterable="@Filterable"
TextField="@TextField" ValueField="@ValueField" Enabled="@Enabled" Id="@ID" Width="100%"
ValueChanged="@ResultValueChanged"></TelerikComboBox></div></div>
@code {
[Parameter] public bool bBindData { get; set; } = false;
[Parameter] public string Label { get; set; }
[Parameter] public T ResultValue { get; set; }
[Parameter] public List<TResource> Resource { get; set; }
[Parameter] public string Placeholder { get; set; } = "Select Item";
[Parameter] public bool Filterable { get; set; } = false;
[Parameter] public string Width { get; set; } = "100%";
[Parameter] public string TextField { get; set; }
[Parameter] public string ValueField { get; set; }
[Parameter] public bool Enabled { get; set; }
[Parameter] public string ID { get; set; } = "TelerikComboBox" + Guid.NewGuid().ToString();
[Parameter] public EventCallback<T> ResultValueChanged { get; set; }
}
DynamicTable.Razor (Componet)
@using System.Linq.Expressions
<div class="card">
<div class="card-body">
@foreach (var item in Contents)
{
@item
;
}
</div>
</div>
@code {
[Parameter]
public List<Blazor_Dynamic.Shared.FabComponet> Componets { get; set; }
public List<RenderFragment> Contents { get; set; }
protected override void OnInitialized()
{
if (Componets.Count() > 0 && Componets != null)
{
CreateFragment();
}
base.OnInitialized();
}
public void CreateFragment()
{
int iComponent = 0;
List<RenderFragment> RFTs = new List<RenderFragment>();
foreach (var area in Componets)
{
RenderFragment renderFragment = (builder) =>
{
object o = new object();
builder.OpenComponent(iComponent, area.Type);
int iDic = 0;
foreach (var item in area.Dic)
{
builder.AddAttribute(iDic, item.Key, item.Value);
}
builder.CloseComponent();
};
RFTs.Add(renderFragment);
}
Contents = RFTs;
}
}
DynamicConnect.razor (Page)
@page "/DynamicConnect"
<h3>DynamicConnect</h3>
@inject IProductRepository IProductRepo
<DynamicTable Componets="@liComponets"></DynamicTable>
<p> @CurrentType </p>
<p> @CurrentProduct </p>
@code {
public List<Product> products { get; set; }
public List<Selection> productTypes { get; set; }
private Selection productType { get; set; }
public Product product { get; set; }
private string CurrentType { get; set; }
private Guid? CurrentProduct { get; set; }
private string sFullProductInfo { get; set; }
public List<FabComponet> liComponets { get; set; }
public class Selection
{
public string id { get; set; }
public string text { get; set; }
}
protected override void OnInitialized()
{
products = IProductRepo.GetProducts();
productTypes = (from w in products group w by w.Type into g select g.First()).Select(x => new Selection { id = x.Type, text = x.Type }).ToList();
List<FabComponet> FCs = new List<FabComponet>();
var dic = new Dictionary<string, object>();
dic.Add("Label", "Product Category");
dic.Add("Resource", productTypes);
dic.Add("ResultValue", CurrentType);
dic.Add("Placeholder", "Select Somthing??");
dic.Add("TextField", "id");
dic.Add("ValueField", "text");
dic.Add("Filterable", false);
dic.Add("Enabled", true);
dic.Add("Id", "cbxType");
dic.Add("Width", "100%");
dic.Add("ResultValueChanged", EventCallback.Factory.Create<System.String>(this, str => TypeSelected(str)));
FabComponet First = new FabComponet() { Type = typeof(FabComboBox<string,Selection>), Row = "1", Length = "6", Seq = "1", Dic = dic };
FCs.Add(First);
var dic2 = new Dictionary<string, object>();
dic2.Add("Label", "Product");
dic2.Add("Resource", products);
dic2.Add("ResultValue", CurrentProduct);
dic2.Add("ValueField", nameof(Product.ID));
dic2.Add("TextField", nameof(Product.ProductName));
dic2.Add("Filterable", false);
dic2.Add("Enabled", (CurrentType != null));
dic2.Add("Id", "cbxProduct");
dic2.Add("Width", "100%");
dic2.Add("ResultValueChanged", EventCallback.Factory.Create<Nullable<System.Guid>>(this, x => ProductSelected(x)));
FabComponet Sec = new FabComponet() { Type = typeof(FabComboBox<Nullable<Guid>,Product>), Row = "1", Length = "6", Seq = "1", Dic = dic2 };
FCs.Add(Sec);
liComponets = FCs;
base.OnInitialized();
}
public void TypeSelected(string SelectionType)
{
products = IProductRepo.GetProductsByType(SelectionType);
productType = productTypes.Where(x => x.id == SelectionType).First();
CurrentType = SelectionType;
}
public void ProductSelected(Guid? SelectionProduct)
{
CurrentProduct = SelectionProduct.HasValue ? SelectionProduct.Value : null;
product = products.Where(p => p.ID == SelectionProduct).First();
}
}
But , When I Change the Value of Product Category , it didn't show what I did Selected , but CurrentType is Changed .
and Product is still Disabled .
Is there any thing went wrong ?
I'm , Using .net Core 6.0 and Visual Studio 2019 Preview .
I've been working with the treelist, but have hit a snag on performance when I have >30 items (and I need >1000). I had hoped that virtualization would save me, but once I included it I found it didn't really help at all.
I've greatly simplified my functionality for my sample code, as my actual code uses OnRowRender, hierarchy, etc etc etc that significantly slows performance. But even in this simple example, you can notice a significant difference.
Notably, paging the treelist is much faster than virtualising it. But I see no reason this should be the case, and hence I think virtualization is not working at all.
Just for completeness, I have included lists and a virtualised list for comparison. You can really spot the big difference when you jump between the tabs.
(note: the refresh button crashes on the virtualized tree list tab example, and doesn't if you turn off virtualization. That's another problem, but not the priority.)
Is this a bug, or am I doing it wrong, or is the Treelist not suitable for 1000 rows?
@page "/"
<TelerikTabStrip Class="LeftPanelTabstrip" TabPosition="Telerik.Blazor.TabPosition.Top">
<TabStripTab Title="paging">
<button @onclick="buttonClick">Refresh</button>
<TelerikTreeList Data="@Data"
IdField="EmployeeId"
ParentIdField="ReportsTo"
Pageable="true"
Class="MyTreeList">
<TreeListColumns>
<TreeListColumn Field="FirstName"></TreeListColumn>
<TreeListColumn Field="LastName"></TreeListColumn>
<TreeListColumn Field="DOB"></TreeListColumn>
<TreeListColumn Field="EmployeeId"></TreeListColumn>
</TreeListColumns>
</TelerikTreeList>
</TabStripTab>
<TabStripTab Title="virtualized">
<button @onclick="buttonClick">Refresh</button>
<TelerikTreeList Data="@Data"
IdField="EmployeeId"
ParentIdField="ReportsTo"
ColumnVirtualization="true" Width="700px" Height="700px"
Class="MyTreeList">
<TreeListColumns>
<TreeListColumn Field="FirstName"></TreeListColumn>
<TreeListColumn Field="LastName"></TreeListColumn>
<TreeListColumn Field="DOB"></TreeListColumn>
<TreeListColumn Field="EmployeeId"></TreeListColumn>
</TreeListColumns>
</TelerikTreeList>
</TabStripTab>
<TabStripTab Title="Not virtualized">
<button @onclick="buttonClick">Refresh</button>
<TelerikTreeList Data="@Data"
IdField="EmployeeId"
ParentIdField="ReportsTo"
Width="700px" Height="700px"
Class="MyTreeList">
<TreeListColumns>
<TreeListColumn Field="FirstName"></TreeListColumn>
<TreeListColumn Field="LastName"></TreeListColumn>
<TreeListColumn Field="DOB"></TreeListColumn>
<TreeListColumn Field="EmployeeId"></TreeListColumn>
</TreeListColumns>
</TelerikTreeList>
</TabStripTab>
<TabStripTab Title="List View">
<button @onclick="buttonClick">Refresh</button>
<TelerikListView Data="@Data" Width="700px" Height="700px">
<Template>
<div style="display: grid;height: 40px;grid-template-columns: 1fr 1fr 1fr 1fr;grid-column-gap: 20px;">
<div>@context.FirstName</div>
<div>@context.LastName</div>
<div>@context.DOB</div>
<div>@context.EmployeeId.ToString()</div>
</div>
</Template>
</TelerikListView>
</TabStripTab>
<TabStripTab Title="virtualize">
<button @onclick="buttonClick">Refresh</button>
<div style="height:700px">
<Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize Items="Data" Context="context">
<tr>
<td>
<div style="display: grid;height: 40px;grid-template-columns: 1fr 1fr 1fr 1fr;grid-column-gap: 20px;">
<div>@context.FirstName</div>
<div>@context.LastName</div>
<div>@context.DOB</div>
<div>@context.EmployeeId.ToString()</div>
</div>
</td>
</tr>
</Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize>
</div>
</TabStripTab>
</TelerikTabStrip>
@code {
public List<Employee> Data { get; set; }
public class Employee
{
public int EmployeeId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string DOB { get; set; }
}
protected override void OnInitialized()
{
Populate();
}
public void Populate()
{
Data = new List<Employee>();
var rand = new Random();
int currentId = 1;
for (int i = 1; i < 3000; i++)
{
string text = rand.Next().ToString();
Data.Add(new Employee()
{
EmployeeId = currentId,
FirstName = text + i.ToString(),
LastName = text + i.ToString(),
DOB = text + i.ToString()
});
currentId++;
}
}
public void buttonClick()
{
Populate();
}
}
Cheers,
Jason