0

im fairly new to WinUI3 and XAML so i have a very specific need right now and that need means adding in code behind dynamicaly a set of controls to a grid, this works just fine and the binding operations are all excelent, except now i need to do this for a listview and inside that listview there are more controls that need to be populated accordingly.

This is fairly easy in XAML, all i have to do is to write something like:

<ListView HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ItemsSource="{x:Bind some_model.some_observableList_of_a_class, Mode=OneWay}">
<ListView.ItemTemplate>
    <DataTemplate>
        <Grid Height="32" Padding="0" Margin="0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="300"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <CheckBox IsThreeState="False" Margin="0" IsChecked="{Binding IsSelected, Mode=TwoWay}" Content="{Binding TextField, Mode=OneWay}"/>
        </Grid>
    </DataTemplate>
</ListView.ItemTemplate>

Doing this in code behind is a bit harder and here is where i need your help, im stuck at the DataTemplate part, i can declare a new instance of it just fine, i can declare a new instance of a grid and inside of it place a new instance of a checkbox. My problem though is i have no idea how to assign the said Grid to the DataTemplate

DataTemplate dataTemplate = new DataTemplate();
Grid listViewItemTemplateGrid = new Grid();
CheckBox cbox = new CheckBox();
listViewItemTemplateGrid.RowDefinitions.Add(new RowDefinition());
listViewItemTemplateGrid.RowDefinitions[0].Height = new GridLength(0, GridUnitType.Auto);
listViewItemTemplateGrid.ColumnDefinitions.Add(new ColumnDefinition());
listViewItemTemplateGrid.ColumnDefinitions[0].Width = new GridLength(0, GridUnitType.Auto);

listViewItemTemplateGrid.Children.Add(cbox);

//here is where i'm stuck
dataTemplate.Children.Add(listViewItemTemplateGrid);//??How can i properly make this happen?

So that's my problem, how can i achieve this feat in C# using WinUi3/UWP?

Thank you all for your help in advance!

Eugen M
  • 51
  • 1
  • 6

1 Answers1

1

I think the only way to create a DataTemplate programmtically in UWP and WinUI is to use the XamlReader.Load API:

const string Xaml = "<DataTemplate xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">" +
"<Grid Height=\"32\" Padding=\"0\" Margin=\"0\">" +
        "<Grid.ColumnDefinitions>" +
            "<ColumnDefinition Width=\"300\"/>" +
        "</Grid.ColumnDefinitions>" +
    "<Grid.RowDefinitions>" +
        "<RowDefinition Height=\"Auto\"/>" +
    "</Grid.RowDefinitions>" +
    "<CheckBox IsThreeState=\"False\" Margin=\"0\" IsChecked=\"{Binding IsSelected, Mode=TwoWay}\" Content=\"{Binding TextField, Mode=OneWay}\"/>" +
    "</Grid>" +
    "</DataTemplate>";

DataTemplate dataTemplate = XamlReader.Load(Xaml) as DataTemplate;

In WPF there is a VisualTree property that you can set to a FrameworkElementFactory but there is no such thing available in WinUI I am afraid.

mm8
  • 163,881
  • 10
  • 57
  • 88
  • Hello, thank you very much for your help, i had no idea that this amazing tool exists, it can be quite powerful indeed, however when i try to do exactly what you say it returns a runtime error "XAML parsing failed." This even happens when trying something as simple as const string Xaml2 = " – Eugen M Apr 06 '22 at 16:10
  • EDIT: NVM i've found the issue, like in you specified in your example, i was missing xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" part Now it works just fine, its also kinda sad we cant use x:Bind declarations in here but thats okay, i'll just use normal binding instead. Working example below: const string Xaml2 = " – Eugen M Apr 06 '22 at 16:58