How to acces Context as TItem

Hi Team, 

I have a SfGrid with:  [Parameter] public IList<TItem> sourceList { get; set; }
How to acces to "myProperty" by Context as TItem? 

@typeparam TItem
...

<Template Context="myContext">
                    @{
                        var af = mycontext as TItem;
                        <Syncfusion.Blazor.Buttons.SfCheckBox CssClass="e-outline e-success" 
                               @bind-Checked=@af.myProperty (?) > </Syncfusion.Blazor.Buttons.SfCheckBox>
                    }
</Template>


Thanks in advance
Regards


14 Replies 1 reply marked as answer

VN Vignesh Natarajan Syncfusion Team January 25, 2021 08:28 AM UTC

Hi Jorge,  
 
Thanks for contacting Syncfusion support.  
 
Query: “How to acces Context as TItem” 
 
We have analyzed your query and we suggest you to achieve your requirement using reflection in C#. refer the below code example.  
 
<GridColumn Field="CustomerID" HeaderText="Customer Name" Width="150"> 
            <Template Context="myContext"> 
                @{ 
                    var af = (TItem)myContext; 
                    System.Reflection.PropertyInfo pi = af.GetType().GetProperty("CustomerID"); 
                    <Syncfusion.Blazor.Buttons.SfCheckBox CssClass="e-outline e-success" 
                                                          Checked=@((bool)(pi.GetValue(af, null)))> </Syncfusion.Blazor.Buttons.SfCheckBox> 
                } 
            </Template> 
        </GridColumn> 
 
Kindly download the sample from below  
 
 
Please get back to us if you have further queries. 
 
Regards,
Vignesh Natarajan
 
 



JQ Jorge Quesada January 26, 2021 02:17 AM UTC

Hi Vignesh Natarajan,

Thanks for the code.
I send you the same example with aggregates (SfDialog modal). I want to bind (two way) bool property using @bind-Checked not Checked, but it does'n work.

<Template Context="myContext">
                @{
                    var af = (TItem)myContext;
                    System.Reflection.PropertyInfo pi = af.GetType().GetProperty("CustomerID");
                    <Syncfusion.Blazor.Buttons.SfCheckBox CssClass="e-outline e-success"
                                                          @bind-Checked=@((bool)(pi.GetValue(af, null)))> </Syncfusion.Blazor.Buttons.SfCheckBox>

                }
</Template>

Thanks in advance.
Regards  

Attachment: DataGrid541798032_V2_6c898760.zip


VN Vignesh Natarajan Syncfusion Team January 27, 2021 04:12 AM UTC

Hi Jorge,   
 
Thanks for the update.  
 
Query: “ I want to bind (two way) bool property using @bind-Checked not Checked, but it does'n work. 
 
We have analyzed your query and we suggest you to modify the solution as below to use two way binding for @bind-Checked property. Refer the below code example.  
 
<SfGrid DataSource="@Orders" AllowPaging="true"> 
    <GridPageSettings PageSize="5"></GridPageSettings> 
    <GridColumns> 
        <GridColumn Field="OrderID" HeaderText="Order ID" TextAlign="TextAlign.Right" Width="120"></GridColumn> 
        <GridColumn Field="CustomerID" HeaderText="Customer Name" Width="150"> 
            <Template Context="myContext"> 
                @{ 
                    var af = (TItem)myContext; 
                    bool val = GetValue(af); 
                    <SfCheckBox CssClass="e-outline e-success"  @bind-Checked=@(val) TChecked="bool"> </SfCheckBox> 
                } 
            </Template> 
        </GridColumn> 
        <GridColumn Field="OrderDate" HeaderText=" Order Date" Format="d" Type="ColumnType.Date" TextAlign="TextAlign.Right" Width="130"></GridColumn> 
        <GridColumn Field="Freight" HeaderText="Freight" Format="C2" TextAlign="TextAlign.Right" Width="120"></GridColumn> 
    </GridColumns> 
</SfGrid> 
  
@code{ 
    [Parameter] 
    public List<TItem> Orders { getset; } 
    public bool GetValue(TItem col) 
    { 
        System.Reflection.PropertyInfo pi = col.GetType().GetProperty("CustomerID"); 
        return (bool)pi.GetValue(col, null); 
    }  
} 
 
 
Please get back to us if you have further queries.     
 
Regards, 
Vignesh Natarajan 



JQ Jorge Quesada January 28, 2021 12:11 AM UTC

Hi Vignesh Natarajan,

Thanks for the solution, but it doesn't work. I click on the checkbox but this action doesn't persist. 
attach the code for your test.

Thanks in advance.
Regards 

Attachment: DataGrid541798032_V3_6a4d7137.zip


VN Vignesh Natarajan Syncfusion Team January 28, 2021 08:10 AM UTC

Hi Jorge, 
 
Sorry for the inconvenience caused.  
 
Query: “Thanks for the solution, but it doesn't work. I click on the checkbox but this action doesn't persist.  
 
We have analyzed the reported query and we are able to reproduce the reproduce the reported issue at our end also. From your query we suspect that you want to save the changes in your databased once value is changed. We have achieved your requirement using ValueChange event of Checkbox component.  
 
Refer the below code example.  
 
<SfGrid @ref="Grid" DataSource="@Orders" AllowPaging="true"> 
    <GridPageSettings PageSize="5"></GridPageSettings> 
    <GridColumns> 
        <GridColumn Field="OrderID" HeaderText="Order ID" TextAlign="TextAlign.Right" Width="120"></GridColumn> 
        <GridColumn Field="CustomerID" HeaderText="Customer Name" Width="150"> 
            <Template Context="myContext"> 
                @{ 
                    var af = (TItem)myContext; 
                    bool val = GetValue(af); 
                    <SfCheckBox CssClass="e-outline e-success" @bind-Checked=@val ValueChange="@((ChangeEventArgs<bool> args) => valueChange(args.Checked,af))"></SfCheckBox> 
                } 
            </Template> 
        </GridColumn> 
        <GridColumn Field="OrderDate" HeaderText=" Order Date" Format="d" Type="ColumnType.Date" TextAlign="TextAlign.Right" Width="130"></GridColumn> 
        <GridColumn Field="Freight" HeaderText="Freight" Format="C2" TextAlign="TextAlign.Right" Width="120"></GridColumn> 
    </GridColumns> 
</SfGrid> 
  
@code{ 
    [Parameter] 
    public List<TItem> Orders { getset; } 
    SfGrid<TItem> Grid { getset; } 
    public bool GetValue(TItem col) 
    { 
        System.Reflection.PropertyInfo pi = col.GetType().GetProperty("CustomerID"); 
        return (bool)pi.GetValue(col, null); 
    } 
  
    public void valueChange(bool va,TItem value) 
    { 
        var idProp = typeof(TItem).GetProperty("OrderID"); 
        if (idProp != null) 
        { 
            object id = value.GetType().GetProperty("OrderID").GetValue(value, null); 
            TItem result = Orders.Where(x => idProp.GetValue(x).Equals(id)).FirstOrDefault(); 
            result.GetType().GetProperty("CustomerID").SetValue(result, va);  
        } 
    } 
 
For your convenience we have prepared a sample which can be downloaded from below  
 
 
Please get back to us if you have further queries.   
 
Regards, 
Vignesh Natarajan    
 


Marked as answer

JQ Jorge Quesada January 29, 2021 03:25 AM UTC

Hi Vignesh Natarajan,

Thanks for your help. The solution works fine. I have to upgrade to the last version because the current one doesn't have ChangeEventArgs<bool> args.

Regards


VN Vignesh Natarajan Syncfusion Team January 29, 2021 04:28 AM UTC

Hi Jorge,  

Thanks for the update.  

We are glad to hear that you have resolved your query using our solution.  

Please get back to us if you have further queries.   

Regards, 
Vignesh Natarajan 



MK Mairis Kalmikovs January 6, 2022 01:50 PM UTC

Hi!

I decided to write in this thread because i have similar issue.

I want to wrap Syncfusion components in my own Base components so the external dependencies are abstracted away in these base components. 


I have Class Person that has property named Country which is of type Enum. I want this property be displayed as DropDownList in Grid.


I have created component called GridDropDownColumnBase. Column gets displayed as expected, but value of this column can't be changed without error. 


As you can see in below image Template renders nicely, but when value is changed then error occurs, that is displayed in Console.



I have added simple demo project that displays vanilla Syncfusion grid and wrapped grid in base components that throws this error.

Am i doing something wrong or this can't be achieved?


Attachment: SimpleDemo_8a3a3968.rar


RN Rahul Narayanasamy Syncfusion Team January 7, 2022 02:10 PM UTC

Hi Mairis, 

Greetings from Syncfusion. 

We have validated your query with the provided details and you want to create custom Grid component. You can create a Custom GridColumn by inheriting the default GridColumn component. Here, we have modified your sample to resolve the problem. Find the below code snippets and sample for your reference. 

Reference: 

<GridBase TValue="Person" Toolbar="Toolbaritems" DataSource=@Persons> 
    <GridColumnBase Field="Id" IsPrimaryKey="true" AllowAdding="false" AllowEditing="false" HeaderText="Id"></GridColumnBase> 
    . . . 
    <GridDropDownColumnBase Field=@nameof(Person.Country) HeaderText="Country"> 
            <EditTemplate> 
                <SfDropDownList ID="Country" FloatLabelType="Syncfusion.Blazor.Inputs.FloatLabelType.Always" 
                                TValue="Countries" TItem="string" 
                                DataSource=@CountriesList @bind-Value=@((context as Person).Country)> 
                </SfDropDownList> 
            </EditTemplate> 
    </GridDropDownColumnBase> 
    <GridColumnBase Field=@nameof(Person.Notes) AllowEditing=true HeaderText="Notes"></GridColumnBase> 
</GridBase> 
[GridDropDownColumnBase.razor] 
@using Syncfusion.Blazor.Grids 
@using static TItemDemo.Pages.Index 
 
@inherits GridColumn 
 
  
<CascadingValue Value="@this"> 
    @ChildContent 
</CascadingValue>  
 
[GridColumnBase.razor] 
 
@using Syncfusion.Blazor.Grids 
@using static TItemDemo.Pages.Index 
 
@inherits GridColumn 
 
  
<CascadingValue Value="@this"> 
    @ChildContent 
</CascadingValue> 


Please let us know if you have any concerns. 

Regards, 
Rahul 



MK Mairis Kalmikovs January 10, 2022 08:11 AM UTC

Hi Rahul,

Thank you for solution, tested it and it works. Didn't thought about inheritance and going that way.


Best regards,

Mairis



MK Mairis Kalmikovs January 10, 2022 04:36 PM UTC

Hi Rahul,

Question about SfDropDownList if i wanted to wrap it also. How 

I tried this: 

@typeparam TValue

@typeparam TItem


@inherits SfDropDownList<TValue, TItem>


<CascadingValue Value="@this">

    @ChildContent

</CascadingValue>


But it doesn't work.




SP Sureshkumar P Syncfusion Team January 11, 2022 04:12 PM UTC

Hi Mairis, 
 
We suggest you create the custom component rendering by below mentioned way to achieve your requirement. 
[DdlComp.razor] 
 
@using Syncfusion.Blazor.DropDowns 
@using System.Linq.Expressions;  
@using static TItemDemo.Pages.Index 
 
@typeparam TVal;  
@typeparam TItemss;  
<SfDropDownList Value="@Value" ValueChanged="ValueChanged" @oninput="@InputHandler" ValueExpression="@ValueExpression" TValue="TVal" TItem="TItemss" ShowClearButton="true" Placeholder="e.g. Australia" DataSource="@Country">  
    <DropDownListFieldSettings Text="Name" Value="Code"></DropDownListFieldSettings>  
</SfDropDownList>  
  
  
@code  
{  
    [Parameter]  
    public List<TItemss> Country { get; set; }  
    private TVal _value { get; set; }  
    [Parameter]  
    public string ID { get; set; }  
    [Parameter]  
    public Expression<Func<TVal>> ValueExpression { get; set; }  
    [Parameter]  
    public TVal Value  
    {  
        get => _value;  
        set  
        {  
            if (!EqualityComparer<TVal>.Default.Equals(value, _value))  
            {  
                _value = value;  
                ValueChanged.InvokeAsync(value);  
            }  
        }  
    }  
    [Parameter]  
    public EventCallback<TVal> ValueChanged { get; set; }  
    [Parameter]  
    public EventCallback<ChangeEventArgs> InputHandler { get; set; }  
  
} 
 
[component.razor] 
 
<DdlComp ID="Country" TVal="string" TItemss=" Countries" Country="@Countri">  
            </DdlComp> 
@code { 
public class Countries 
    { 
        public string Name { get; set; } 
 
        public string Code { get; set; } 
    } 
 
    List<Countries> Countri = new List<Countries> 
    { 
        new Countries() { Name = "Australia", Code = "AU" }, 
        new Countries() { Name = "Bermuda", Code = "BM" }, 
        new Countries() { Name = "Canada", Code = "CA" }, 
        new Countries() { Name = "Cameroon", Code = "CM" }, 
        new Countries() { Name = "Denmark", Code = "DK" }, 
        new Countries() { Name = "France", Code = "FR" }, 
        new Countries() { Name = "Finland", Code = "FI" }         
    }; 
 
 
} 
 
Regards, 
Sureshkumar P 



MK Mairis Kalmikovs January 12, 2022 12:17 PM UTC

Hi Sureshkumar,

This is gold, i can combine it together with previous solution to get desired result.

Thank you!

Best regards,

Mairis



SP Sureshkumar P Syncfusion Team January 13, 2022 09:11 AM UTC

Hi Mairis, 
 
Thanks for your update. 
 
Regards, 
Sureshkumar P 


Loader.
Up arrow icon