How do I set displayed text in DataGridBooleanColumn (defined in C#, not XAML) to desired strings, rather than the defaults?

1 Answer 340 Views
DataGrid
David
Top achievements
Rank 1
Iron
David asked on 12 Apr 2022, 05:27 PM

Documentation of this Column type is unhelpful and has no examples for either CellContentFormat (which it notes is Framework dependent)  or CellContentTemplate.

In the more general ColumnsCellTemplates document there is a Boolean CellContentTemplate in XAML, but not in C# and I have found translating from the XAML to C# is yet to work for me.

Lance | Manager Technical Support
Telerik team
commented on 12 Apr 2022, 10:41 PM

I also wanted to add a comment up top here now that I have a better understanding of what you want for this specific column. There is no requirement that you have to use BooleanColumn. We provide that as a quick and easy option if you only want a single column for users to toggle.

If you want better control over the appearance with other elements and more custom text, you can use a TemplateColumninstead. In the normal content template, just use a Label with your converter (see my comment below that explains converters) and in the Edit template, use a Switch and a Label.

Option 1. XAML

<dg:DataGridTemplateColumn HeaderText="Presence">
    <!-- The normal display template only shows the custom text you want-->
    <dg:DataGridTemplateColumn.CellContentTemplate>
        <DataTemplate>
            <Label Text="{Binding IsAbsent, Converter={StaticResource BoolToAbsentConv}}" />
        </DataTemplate>
    </dg:DataGridTemplateColumn.CellContentTemplate>

    <!-- The Edit template stacks botht he switch and a Label for your custom text-->
    <dg:DataGridTemplateColumn.CellEditTemplate>
        <DataTemplate>
            <HorizontalStackLayout>
                <Switch IsToggled="{Binding IsAbsent, Mode=TwoWay}" />
                <Label Text="{Binding IsAbsent, Converter={StaticResource BoolToAbsentConv}}" />
            </HorizontalStackLayout>
        </DataTemplate>
    </dg:DataGridTemplateColumn.CellEditTemplate>
</dg:DataGridTemplateColumn>

Option 2. C#

var column1 = new DataGridTemplateColumn();
        column1.HeaderText = "Presense";
        column1.CellContentTemplate = new DataTemplate(() =>
        {
            var label = new Label();

            label.SetBinding(
                Label.TextProperty,
                nameof(Student.IsAbsent),
                converter: new BoolToIsAbsentConverter());

            return label;
        });
        column1.CellEditTemplate = new DataTemplate(() =>
        {
            var sl = new HorizontalStackLayout();
            
            var label = new Label();
            label.SetBinding(
                Label.TextProperty,
                nameof(Student.IsAbsent),
                converter: new BoolToIsAbsentConverter());

            var switch1 = new Switch(); ;
            switch1.SetBinding(
                Switch.IsToggledProperty,
                nameof(Student.IsAbsent));

            sl.Children.Add(label);
            sl.Children.Add(switch1);

            return sl;
        });

1 Answer, 1 is accepted

Sort by
0
Lance | Manager Technical Support
Telerik team
answered on 12 Apr 2022, 05:50 PM

Hello David,

These properties are Microsoft API objects/values that are used everywhere else, which is why we do not document them. I will talk to the development team about adding some C# examples to the SDK Examples and/or the docs. Generally speaking it is the same StringFormat and same DataTemplate you use anywhere else and is not specific to Telerik controls or Telerik API.

CellContentFormat is just a typical string format, something like "{0:N2}"

However, if you are also defining your own custom CellContentTemplate, you are overriding any of these other format options because you are now 100% responsible for the cell's content.

So, you will need to drop back to Microsoft APIs and values for the custom content binding. Here's an example of that same format string, but it's now being applied t the binding of the Label inside the DataTempate

If you are not familiar with defining a DataTemplate in C#, you can find many examples online Creating a Xamarin.Forms DataTemplate - Xamarin | Microsoft Docs 

Note: you can use Xamarin.Forms documentation in your searches because MAUI XAML/C# is the same thing as Xamarin.Forms XAML/C# with the exception of .NET 6-only APIs.

Namespace Warning

Make sure you are using the correct DataGridTextColumn object in C# because the same object name exists in two namespaces. There's a cross platform one (which you should use) and there's a native WinUI one (which you should not use for your MAUI XAML). I suspect that is why you're seeing a "framework dependent" warning.

Notice my screenshot above, I have intentionally fully qualified the namespace so you can use that for a using statement at the top of your class.

Regards,
Lance | Manager Technical Support
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

David
Top achievements
Rank 1
Iron
commented on 12 Apr 2022, 07:42 PM

I appreciate the quick response. I had already checked the references you supplied and still am in despair how to apply any to Booleans. For example, just what string.format to you suggest using to render a boolean in text as something other than true or false? Same with the DateTemplete. It would be so much easier if you could, at least for the Boolean column, furnish an actual example or two, especially in C#.
Lance | Manager Technical Support
Telerik team
commented on 12 Apr 2022, 07:42 PM

As a side note, I am investigating why the .NET MAUI preview14 DataTemplate object will not let you use a lambda expression to set the content. It fails, expecting a type instead, but even when I use a type it still fails.

Until I figure out a way around this, or it is fixed in the next preview release, I do not see a way that you can create a DataTemplate in C# for the CellContentTemplate (or CellEditTemplate) right now.

Lance | Manager Technical Support
Telerik team
commented on 12 Apr 2022, 10:24 PM

Hi David, I didn't see your comment as I was in the middle of crafting the reply above. I can give you a quick answer about how the string format works so that you can plan accordingly.

The "0" part of the format string is just the value of the binding, whatever that value is going to be. Take a look at this Microsoft Documentation for many examples of string formatting and how they're used

  • If it is a numerical value, you can use numerical formatters like
    • C2 "You have {0:C2} remaining" will render as You have $2.50 remaining
    • P1 "Your grade is {0:P1}" will render as Your grade is 100%
  • If it is a DateTime object, you can use date formatters like
    • g "{0:g}" will render as 6/15/2009 1:45 PM (for the US region)

For a bool, it is just going to be the ToString version of that value. For example "Is Absent? {0}" will render as Is Absent? False at runtime

I recommend bookmarking this .NET documentation (I have it bookmarked and reference it frequently):

Converter

I suspect you might be looking for converter that gives you more control. In most cases a simple Stringformat gives you enough to get the result, but there are other times that the object is a complex object or you want to do something different with a bool.

Here's an example that will return a human readable value for a bool:

public class BoolToIsAbsentConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if(value is bool isAbsent)
        {
            if (isAbsent)
            {
                return "Student is Absent";
            }
            else
            {
                return "Student is Present";
            }
        }

        return "no result";
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

A Binding accepts an instance of a converter, and the binding passes the value of the bound object to the converter and accepts whatever it returns.

Here's what it looks like in XAML

<Grid x:Name="RootGrid">
    <Grid.Resources>
        <local:BoolToIsAbsentConverter x:Key="BoolToAbsentConv" />
    </Grid.Resources>

    <Label Text="{Binding IsAbsent, Converter={StaticResource BoolToAbsentConv}}" />
</Grid>

and here is what that looks like in C#:

myLabel.SetBinding(
            Label.TextProperty,
            nameof(Student.IsAbsent),
            converter: new BoolToIsAbsentConverter());

Tags
DataGrid
Asked by
David
Top achievements
Rank 1
Iron
Answers by
Lance | Manager Technical Support
Telerik team
Share this question
or