#components #blazor #blazor-server-side
#Компоненты #блейзор #blazor-серверная часть
Вопрос:
Я пытаюсь создать универсальный раскрывающийся компонент для использования в нашей системе. Однако я сталкиваюсь с проблемами при привязке EventCallback
при изменении выбранного элемента.
Это мои текущие размышления по поводу общего выпадающего списка:
lt;div class="inputItem @(SizeClass) dropdown" style="min-width:@(Width);"gt; lt;SfDropDownList TItem="object" TValue="int" Placeholder="Select a category" DataSource="DataSource" Value="@(SelectedItem)" EnableVirtualization="true"gt; lt;DropDownListEvents TItem="object" TValue="int" ValueChange="@OnSelectedItemChanged"gt;lt;/DropDownListEventsgt; lt;DropDownListFieldSettings Text="@(TextField)" Value="@(ValueField)" /gt; lt;/SfDropDownListgt; lt;/divgt; @code { [Parameter] public IEnumerablelt;objectgt; DataSource { get; set; } [Parameter] public EventCallbacklt;ChangeEventArgslt;int, objectgt;gt; OnSelectedItemChanged { get; set; } [Parameter] public string Placeholder { get; set; } [Parameter] public string TextField { get; set; } [Parameter] public int SelectedItem { get; set; } [Parameter] public string ValueField { get; set; } [Parameter] public string Width { get; set; } [Parameter] public string SizeClass { get; set; } }
И вот один пример компонента, который назвал бы это:
@page "/news/create" @inject NavigationManager NavManager; @using Microsoft.EntityFrameworkCore; @inject IDbContextFactorylt;FIS2_DbContextgt; contextFactory; @inject IFileService fileService; @using FIS2withSyncfusion.Controls; @using FIS2withSyncfusion.Models; @using FIS2withSyncfusion.Utility; @using Syncfusion.Blazor.RichTextEditor; @using System.Collections.Generic; @using System.Threading.Tasks; @using Newtonsoft.Json; lt;div class="dashWrapper"gt; lt;SfDashboardLayout AllowDragging="false" AllowFloating="false" AllowResizing="false" CellAspectRatio="2.5" CellSpacing="@(new double[]{20,20})" Columns="3"gt; lt;DashboardLayoutPanelsgt; lt;DashboardLayoutPanel Column="0" Row="0" SizeX="2" SizeY="2" Id="createNews"gt; lt;HeaderTemplategt; lt;h3gt;Create A News Itemlt;/h3gt; lt;/HeaderTemplategt; lt;ContentTemplategt; lt;div class="form-wrapper"gt; lt;div class="inputRow"gt; lt;TextBox AutoComplete="@(Syncfusion.Blazor.Inputs.AutoComplete.Off)" Placeholder="Title" Text="@(title)" HTMLAttributes="@textboxValidation" Width="450px" SizeClass="half-width"gt;lt;/TextBoxgt; lt;DropDownList DataSource="categories" Placeholder="Select a category" SizeClass="half-width" Width="450px" TextField="name" ValueField="id" SelectedItem="@(itemModel.Category)" OnSelectedItemChanged="@(OnSelectedItemChanged)"gt;lt;/DropDownListgt; @*lt;SfDropDownList TItem="spGetNewsCategoriesResult" TValue="int" Placeholder="Select a category" @ref="sfDropDown" DataSource="categories" CssClass="inputItem half-width" @bind-Value="@(itemModel.Category)"gt; lt;DropDownListFieldSettings Text="name" Value="id" /gt; lt;/SfDropDownListgt;*@ lt;/divgt; lt;div class="inputRow"gt; lt;CheckBox Checked="isChecked" Label="Suggest Dates This Should Be Active?" OnCheckChange="@(OnCheckChange)" SizeClass="one-third" Width="300px"gt;lt;/CheckBoxgt; @if (isChecked) { lt;DateTimePicker Label="Active From:" SelectedDate="@activeFrom" Width="450px" SizeClass="one-third"gt;lt;/DateTimePickergt; lt;DateTimePicker Label="Active To:" SelectedDate="@activeTo" Width="450px" SizeClass="one-third"gt;lt;/DateTimePickergt; } lt;/divgt; lt;div class="inputRow"gt; lt;FileUploader MaxSize="@(MaxSize)" OnClearFiles="OnClearFiles" OnFileRemove="OnFileRemove" OnFileUpload="OnFileUpload" SizeClass="full-width" Width="400px"gt;lt;/FileUploadergt; lt;/divgt; lt;RichTextEditor DeniedAttributes="@DeniedAttributes" text=@(itemModel.Content) Height="400px" Width="1600px"gt;lt;/RichTextEditorgt; lt;/divgt; lt;/ContentTemplategt; lt;/DashboardLayoutPanelgt; lt;/DashboardLayoutPanelsgt; lt;/SfDashboardLayoutgt; lt;/divgt; @if (ShowDialog) { lt;Dialog Title="Create News Item" message="@Message" OKText="@OKText" cancelText="@CancelText" OnClose="OnDialogClose"gt; lt;/Dialoggt; } @code { [CascadingParameter] Tasklt;AuthenticationStategt; authenticationStateTask { get; set; } public string userName { get; set; } private int MaxSize { get; set; } private string title { get; set; } private int selectedCategory { get; set; } private string content { get; set; } int count { get; set; } private bool ShowDialog { get; set; } = false; private string Message { get; set; } = ""; private string OKText { get; set; } = ""; private string CancelText { get; set; } = ""; public DateTime activeTo { get; set; } public DateTime activeFrom { get; set; } private bool isChecked { get; set; } SaveNewsItemModel itemModel = new SaveNewsItemModel(); Listlt;stringgt; DeniedAttributes = new Listlt;stringgt;() { "id", "title", "style" }; Dictionarylt;string, objectgt; textboxValidation = new Dictionarylt;string, objectgt;(){ {"maxlength", "100"} }; Listlt;spGetNewsCategoriesResultgt; categories = new Listlt;spGetNewsCategoriesResultgt;(); private async Task OnCheckChange(bool check) { isChecked = check; StateHasChanged(); } protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { var authState = await authenticationStateTask; var user = authState.User; userName = user.Identity.Name; var context = contextFactory.CreateDbContext(); var procedures = context.Procedures; categories = await procedures.spGetNewsCategoriesAsync(); MaxSize = 15 * 1024 * 1024; } } private Listlt;ToolbarItemModelgt; Tools = new Listlt;ToolbarItemModelgt;() { new ToolbarItemModel() { Command = ToolbarCommand.Bold }, new ToolbarItemModel() { Command = ToolbarCommand.Italic }, new ToolbarItemModel() { Command= ToolbarCommand.Underline }, new ToolbarItemModel() { Command= ToolbarCommand.Separator }, new ToolbarItemModel() { Command = ToolbarCommand.Undo }, new ToolbarItemModel() { Command = ToolbarCommand.Redo }, new ToolbarItemModel() { Command= ToolbarCommand.Separator }, new ToolbarItemModel() { Command = ToolbarCommand.OrderedList }, new ToolbarItemModel() { Command = ToolbarCommand.UnorderedList }, new ToolbarItemModel() { Command = ToolbarCommand.Separator }, new ToolbarItemModel() { Command = ToolbarCommand.FontColor }, new ToolbarItemModel() { Command = ToolbarCommand.CreateLink }, new ToolbarItemModel() { Command = ToolbarCommand.RemoveLink } }; private async Task OnFileUpload(UploadChangeEventArgs args) { foreach (var file in args.Files) { var fileName = file.FileInfo.Name; using (var ms = file.Stream) { System.IO.FileInfo fileInfo = new System.IO.FileInfo(fileName); int count = 1; string tempFileName = fileName; while (fileService.TempFileExists(tempFileName)) { tempFileName = $"({count}) {fileName}"; count ; } var bytes = ms.ToArray(); await fileService.SaveFileToTempAsync(bytes, tempFileName); var mimetype = fileInfo.Extension; itemModel.AddFile(fileName, mimetype, tempFileName, contextFactory); } } } private async Task OnClearFiles(ClearingEventArgs args) { foreach (var file in args.FilesData) { var fileName = file.Name; System.IO.FileInfo fileInfo = new System.IO.FileInfo(fileName); itemModel.RemoveFile(fileName, fileInfo.Extension, contextFactory, fileService); } } private async Task OnFileRemove(RemovingEventArgs args) { foreach (var file in args.FilesData) { var fileName = file.Name; System.IO.FileInfo fileInfo = new System.IO.FileInfo(fileName); itemModel.RemoveFile(fileName, fileInfo.Extension, contextFactory, fileService); } } private async Task OnSelectedItemChanged(ChangeEventArgslt;int, spGetNewsCategoriesResultgt; eventArgs) { itemModel.Category = eventArgs.Value; StateHasChanged(); } private async Task OnSave() { if (isChecked) { itemModel.RequestDates(activeFrom, activeTo); } var context = contextFactory.CreateDbContext(); var procedures = context.Procedures; var addedFiles = await procedures.spCreateNewsItemAsync(JsonConvert.SerializeObject(itemModel), userName); if (addedFiles.Count gt; 0) { foreach (var file in addedFiles) { await fileService.MoveTempToNewsAsync(file.fileName, file.newsID, file.fileID); } } Message = "This has been successfully saved and is now pending review; pressing OK will refresh the page."; OKText = "OK"; ShowDialog = true; } private async Task OnDialogClose(bool r) { ShowDialog = false; NavManager.NavigateTo(NavManager.Uri, true); } }
Моя проблема в том, что на данный момент я получаю ошибку: OnSelectedItemChanged="@(OnSelectedItemChanged)"
Ошибка в том, что:
Не удается преобразовать из
method group
вEventCallback
Охота, которую я провел, похоже, подразумевает, что мне нужно явно передать тип в качестве параметра, вместо того, чтобы использовать object
и пытаться вывести его во время выполнения — я просто немного запутался в деталях того, как это сделать?
TValue
быть собой int
-это то, что нигде не должно меняться. Но TItem
это может быть что угодно (в данном конкретном сценарии это а spGetNewsCategoriesResult
) — как мне это удовлетворить?
Ответ №1:
После долгих поисков и возни я нашел решение. Изменив компонент на этот:
@typeparam T lt;div class="inputItem @(SizeClass) dropdown" style="min-width:@(Width);"gt; lt;SfDropDownList TItem="T" TValue="int" Placeholder="Select a category" DataSource="DataSource" Value="@(SelectedItem)" EnableVirtualization="true"gt; lt;DropDownListEvents TItem="T" TValue="int" ValueChange="@OnSelectedItemChanged"gt;lt;/DropDownListEventsgt; lt;DropDownListFieldSettings Text="@(TextField)" Value="@(ValueField)" /gt; lt;/SfDropDownListgt; lt;/divgt; @code { [Parameter] public IEnumerablelt;Tgt; DataSource { get; set; } [Parameter] public EventCallbacklt;Syncfusion.Blazor.DropDowns.ChangeEventArgslt;int, Tgt;gt; OnSelectedItemChanged { get; set; } [Parameter] public string Placeholder { get; set; } [Parameter] public string TextField { get; set; } [Parameter] public int SelectedItem { get; set; } [Parameter] public string ValueField { get; set; } [Parameter] public string Width { get; set; } [Parameter] public string SizeClass { get; set; } }
И ссылаться на него как на таковое:
lt;DropDownList DataSource="categories" Placeholder="Select a category" SizeClass="half-width" Width="450px" TextField="name" ValueField="id" SelectedItem="@(itemModel.Category)" OnSelectedItemChanged="@(OnSelectedItemChanged)" T="spGetNewsCategoriesResult"gt;lt;/DropDownListgt;
Ошибка устранена. Решил ответить на свой собственный вопрос, а не просто удалить его, потому что я подумал, что он, вероятно, появится у людей в их собственном поиске.