Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    ADV
    @Adevien
    Who came with the idea to split the Blazorise into modules is a genius.
    Mladen Macanović
    @stsrki
    @Adevien Not sure if sarcasm or not 😅
    But, I'm guilty of that 🤣
    Mladen Macanović
    @stsrki
    @/all Blazorise is updated to .Net 5 RC2 and is available as part of the preview 10
    Mitchell Currey
    @MitchellNZ
    @techierathore Also a good idea! I will add that to the list too (tracking at stsrki/Blazorise#1304)
    However, I'm probably not going to get chance to work on Blazorise until the end of the month.
    ADV
    @Adevien
    @stsrki not sarcasm, its very good, especially for PWA's
    Mladen Macanović
    @stsrki
    @Adevien Thank you 😊
    ADV
    @Adevien
    However i haven't managed to actually get it working into a Blazor WASM
    Mladen Macanović
    @stsrki
    @Adevien Which part is not working for you?
    htwashere
    @htwashere
    @stsrki Hi, I came across your chat site here after experimenting with your wonderful Blazorise Data Grid and I was following the same thread above about doing UseInternalEditing="false" RowUpdated="@OnRowUpdated. I got the OnRowUpdated event to fire and it can execute my code block. My question is, how do i get the context of the row that i am updating? I am fairly new to this and especially <TItem> concept, I hope you can shed some light on how I can refer to the row being changed in my code....thank you
    Mladen Macanović
    @stsrki
    @htwashere You're on right track. The real "context" for RowUpdated is the dictionary with the changed Values
    Task OnRowUpdated( SavedRowItem<Employee, Dictionary<string, object>> e )
    {
        return Task.CompletedTask;
    }
    2 replies
    e.Values will contain all the new values, while e.Item is there just for the reference to the item that is being changed. You should never update it, just read in case you need some extra information that are not present in the e.Values
    Stefan Ossendorf
    @StefanOssendorf
    Good morning guys. Does anyone have an Idea why the following file upload apporach can't handle large files? (I'm testing with a 212MB big pdf file)
    protected async Task FilesSelected(FileChangedEventArgs e)
    {
        // brevity...
        foreach ( var file in e.Files )
        {
            Console.WriteLine($"Started to process file {file.Name}.");
            using var transferStream = new MemoryStream();
    
            await file.WriteToStreamAsync(transferStream).ConfigureAwait(false);
            Console.WriteLine("File read into transfer stream.");
    
            transferStream.Seek(0, SeekOrigin.Begin);
    
            Console.WriteLine("File read into transfer stream will be uploaded.");
            var fileId = await JobsClient.FilesPostAsync(SelectedJob.Job.Id, new FileParameter(transferStream, file.Name), CancellationToken).ConfigureAwait(false);
    
            Console.WriteLine($"File uploaded and got file ID {fileId}.");
        }
    }
    I always get an OutOfMemoryException during the WriteToStreamAsync call. But I don't know how to stream (?) it to my api.
    Stefan Ossendorf
    @StefanOssendorf
    The FilesPostAsync method is generated from swagger/openapi and the server accepts an IFormFile if this helps.
    Mladen Macanović
    @stsrki
    @StefanOssendorf Stupid question, but do you have enough memory? 😅
    Only I can think if is that Blazor is refreshing the page while reading the file and GC is not fast enough to collect
    One optimization you do is to create a separate component where you can place FileEdit, for example UploadComponent. It will basically be just a wrapper, but the benefit is that it will refresh only that part of the page. Meaning also that it will not block UI
    Stefan Ossendorf
    @StefanOssendorf
    16GB of RAM :-D
    This is already in it's own component with only one button besides it. So that won't help - I think ^^".
    Stefan Ossendorf
    @StefanOssendorf
    But yeah Iam refreshing the component to update the progress.
    Mladen Macanović
    @stsrki
    @StefanOssendorf I just tried with files over 700MB and it's working just fine
    Here is my Upload.razor
    <Addons>
        @if ( Uploading )
        {
            <Addon AddonType="AddonType.Start">
                <AddonLabel Style="color: red;">
                    @($"{Uploaded} %")
                </AddonLabel>
            </Addon>
        }
        <Addon AddonType="AddonType.Body">
            <FileEdit Multiple="false" Disabled="@Uploading"
                      Changed="@OnFileChanged"
                      Started="@OnFileStarted"
                      Ended="@OnFileEnded"
                      Progressed="@OnFileProgressed"
                      Attributes="@Attributes" />
        </Addon>
    </Addons>
    public partial class Upload : IDisposable
    {
        #region Members
    
        private MemoryStream stream;
    
        private string fileName;
    
        #endregion
    
        #region Methods
    
        public void Dispose()
        {
            if ( stream != null )
            {
                stream.Dispose();
                stream = null;
            }
        }
    
        private async Task OnFileChanged( FileChangedEventArgs e )
        {
            try
            {
                foreach ( var file in e.Files )
                {
                    stream?.Dispose();
    
                    stream = new MemoryStream();
                    fileName = file.Name;
    
                    await file.WriteToStreamAsync( stream );
    
                    // Set the capacity to be be the same as file length or otherwise
                    // after the upload file will be larger and currupted.
                    stream.Capacity = (int)stream.Length;
                }
            }
            catch
            {
                await Error.InvokeAsync( "Error uploading image!" );
            }
            finally
            {
                StateHasChanged();
            }
        }
    
        private Task OnFileStarted( FileStartedEventArgs e )
        {
            Uploading = true;
            Uploaded = 0;
    
            return Task.CompletedTask;
        }
    
        private Task OnFileEnded( FileEndedEventArgs e )
        {
            Uploading = false;
            Uploaded = 100;
    
            if ( !e.Success )
                return Finished.InvokeAsync( null );
    
            return Finished.InvokeAsync( new UploadFinishedEventArgs( stream, fileName ) );
        }
    
        private void OnFileProgressed( FileProgressedEventArgs e )
        {
            if ( (int)e.Percentage > Uploaded )
            {
                Uploaded = (int)e.Percentage;
    
                InvokeAsync( () => StateHasChanged() );
            }
        }
    
        #endregion
    
        #region Properties
    
        private bool Uploading { get; set; }
    
        private int Uploaded { get; set; } = 0;
    
        [Parameter] public EventCallback<UploadFinishedEventArgs> Finished { get; set; }
    
        [Parameter] public EventCallback<string> Error { get; set; }
    
        [Parameter( CaptureUnmatchedValues = true )]
        public Dictionary<string, object> Attributes { get; set; }
    
        #endregion
    }
    
    public class UploadFinishedEventArgs : EventArgs
    {
        public UploadFinishedEventArgs( MemoryStream stream, string fileName )
        {
            Stream = stream;
            FileName = fileName;
        }
    
        public MemoryStream Stream { get; }
    
        public string FileName { get; }
    }
    Stefan Ossendorf
    @StefanOssendorf
    @stsrki Thanks a lot man! I'll try it today or on monday :-D
    Mladen Macanović
    @stsrki
    You're welcome :)
    Elton
    @eltonr98
    Heyo! I'm back with my weird questions!
    I have an array of bools and set it to the size of an enum count, then i go through an foreach loop for each value in the enum and set a bind to the bool array with a counter. but when I change or flip the switch (which I am using) the value doesnt change!
    I'll check back on monday, Have a nice evening everyone! :)
    @foreach (var value in Enum.GetValues(typeof(UnitEventType)))
    {
        string name = Enum.GetName(typeof(UnitEventType), value);
        <Switch @bind-Checked="@check[counter]" TValue="bool">@name</Switch>
        counter++;
    }
    Stefan Ossendorf
    @StefanOssendorf
    @eltonr98 Is it even possible to have a binding expression on an indexer? Shouldn't you try to create a dedicated item which state is toggled?
    Elton
    @eltonr98
    Not sure @StefanOssendorf but since I don't know if there will be stuff added or removed to the Enum I want it to be modular. Maybe someone knows if it works
    Stefan Ossendorf
    @StefanOssendorf
    I would use a container like UICheck<Enum> { Enum Value; Boolean Checked; Int Key}.
    With that you have a property to bind against.
    Mladen Macanović
    @stsrki
    @StefanOssendorf That is a good approach and it should work I think
    Stefan Ossendorf
    @StefanOssendorf
    @stsrki :) I'm still trying to use your file upload example. In our current app it still does not work. Somehow FF/Edges memory is exploding. I'm trying to upload a 212MB PDF and the used RAM grows to >1.5GB. Now I'm creating a fresh CSB project and look if the same error still happens with your provided component. I hope it works and I figure out why not in our app xD
    Elton
    @eltonr98
    @StefanOssendorf What is UICheck here? Not quite sure I follow
    Stefan Ossendorf
    @StefanOssendorf
    @eltonr98 It's a custom class you have to create to wrap the value+boolen
    This is the implementation I use for e.g. check box lists created from an enum:
    /// <summary>
        /// Container for check box controls which associate a specific value with enabled/disabled.
        /// </summary>
        /// <typeparam name="T">The type of the associated value.</typeparam>
        public class CheckBoxItem<T>
        {
            /// <summary>
            /// Gets or sets a key intended to be used for Blazor to handle UI updates more efficient.
            /// </summary>
            /// <value>The key for this item for Blazor.</value>
            /// <remarks>The user is responsible for creating unique keys.</remarks>
            public Int32 Key
            {
                get; set;
            }
    
            /// <summary>
            /// Gets the value associated to this item.
            /// </summary>
            /// <value>The associated value to this item.</value>
            public T Value
            {
                get;
            }
    
            /// <summary>
            /// Gets or sets whether this item is checked.
            /// </summary>
            /// <value><c>true</c> if this item is checked. Otherwise <c>false</c>.</value>
            public Boolean IsChecked
            {
                get; set;
            }
    
            /// <summary>
            /// Initializes a new instance of <see cref="CheckBoxItem{T}"/>.
            /// </summary>
            /// <param name="value">The value.</param>
            public CheckBoxItem(T value)
            {
                Value = value;
            }
        }
    Stefan Ossendorf
    @StefanOssendorf
    @stsrki Even a new CSB project with only Blazorise and your upload snippet from above can't handle my 212MB pdf file ^^".
    Stefan Ossendorf
    @StefanOssendorf
    I tested this with .NetCore3.1 if that's important.
    Mladen Macanović
    @stsrki
    @StefanOssendorf I tested with SSB only since I didn't need CSB for my project ...
    Stefan Ossendorf
    @StefanOssendorf
    Ah okay :-/
    Mladen Macanović
    @stsrki
    I will try to test it later with CSB if I have some free time
    Stefan Ossendorf
    @StefanOssendorf
    Thanks :-)
    Stefan Ossendorf
    @StefanOssendorf
    Is multi select possible in the datagrid?
    Mladen Macanović
    @stsrki
    @StefanOssendorf There is not anything like DataGridMultiSelect, but you can use any column and then implement it with EditTemplate
    Stefan Ossendorf
    @StefanOssendorf
    How can an edit template help me with multi select?
    Btw good morning :)
    Mladen Macanović
    @stsrki
    @StefanOssendorf Here is an example. I did not try it
    <DataGridColumn TItem="Employee" Field="@nameof( Employee.Values )" Editable="true">
        <DisplayTemplate>
            @{
                @foreach ( var v in context.Values )
                {
                    <span>@v</span>
                }
            }
        </DisplayTemplate>
        <EditTemplate>
            <Select TValue="string" SelectedValues="@((string[])( ( (CellEditContext)context ).CellValue ))" SelectedValuesChanged="@(( v ) => ( (CellEditContext)context ).CellValue = v)">
                <SelectItem TValue="string" Value="@("1")">1</SelectItem>
                <SelectItem TValue="string" Value="@("2")">2</SelectItem>
                <SelectItem TValue="string" Value="@("3")">3</SelectItem>
            </Select>
        </EditTemplate>
    </DataGridColumn>
    Stefan Ossendorf
    @StefanOssendorf
    Ahh! Thanks but I think I did not explain it properly. Is row multi selection possible. Not an edit cell with a multi selection control in it.
    Like I want to select row 1 and 3 with Ctrl+MouseClick with highlighting and (preferrably) a collection of selected items.
    Mladen Macanović
    @stsrki
    @StefanOssendorf aaaaah that :) 🤔 I think currently only one row can be selected. I would be a good feature to have multi-select
    Stefan Ossendorf
    @StefanOssendorf
    @stsrki That would be awesome :) Otherwise I need to find another grid 😅 control.
    I need to do more stuff with Blazor and free time to contribute to your awesome lib :> :)