Home > Software engineering >  Use a dynamic custom cell inside a datagrid template column
Use a dynamic custom cell inside a datagrid template column

Time:12-08

I've currently got a DataGrid containing text. I would like to add a dynamic custom layout to one of these columns. The layout will be based on how many items there are in a list. I am however unsure how I need to initialize the custom cell or how to add it to the cell.

The dynamic custom cell needs to look something like the following:

foreach (var item in collection)
        {
            TextBox tb = new TextBox();
            tb.Name = item.Name;
            tb.ToolTip = item.Value;
        }

And then needs to be added to the DataGrid

<DataGrid x:Name="DataGridName">
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="ColumnName">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <"DYNAMIC CUSTOM CELL"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>

I've searched around, but I was not able to find enough information to do this, so help would be much appreciated!

Edit: Here is more information on how the underlying code: Currently the datagrid looks as the following:

<DataGrid x:Name="creatureDatagrid">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
        <DataGridTextColumn Header="maxHP" Binding="{Binding MaxHp}"/>
        <DataGridTextColumn Header="AC" Binding="{Binding Ac}"/>
        <DataGridTextColumn Header="INIT" Binding="{Binding Init}"/>
        <DataGridTextColumn Header="HP" Binding="{Binding Hp}"/>
        <DataGridTextColumn Header="Protection" Binding="{Binding StrProtection}"/>
        <DataGridTextColumn Header="Speed" Binding="{Binding StrSpeed}"/>
        <DataGridTextColumn Header="Senses" Binding="{Binding StrSenses}"/>
        <DataGridTemplateColumn Header="Traits">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Traits[0].Name}" ToolTip="{Binding Traits[0].Value}" Margin="2,0"/>
                        <TextBlock Text="{Binding Traits[1].Name}" ToolTip="{Binding Traits[1].Value}" Margin="2,0"/>
                        <TextBlock Text="{Binding Traits[2].Name}" ToolTip="{Binding Traits[2].Value}" Margin="2,0"/>
                        <TextBlock Text="{Binding Traits[3].Name}" ToolTip="{Binding Traits[3].Value}" Margin="2,0"/>
                        <TextBlock Text="{Binding Traits[4].Name}" ToolTip="{Binding Traits[4].Value}" Margin="2,0"/>
                        <TextBlock Text="{Binding Traits[5].Name}" ToolTip="{Binding Traits[5].Value}" Margin="2,0"/>
                        <TextBlock Text="{Binding Traits[6].Name}" ToolTip="{Binding Traits[6].Value}" Margin="2,0"/>
                        <TextBlock Text="{Binding Traits[7].Name}" ToolTip="{Binding Traits[7].Value}" Margin="2,0"/>
                        <TextBlock Text="{Binding Traits[8].Name}" ToolTip="{Binding Traits[8].Value}" Margin="2,0"/>
                        <TextBlock Text="{Binding Traits[9].Name}" ToolTip="{Binding Traits[9].Value}" Margin="2,0"/>
                        <TextBlock Text="{Binding Traits[10].Name}" ToolTip="{Binding Traits[10].Value}" Margin="2,0"/>
                    </StackPanel>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTextColumn Header="Actions" Binding="{Binding StrActions}"/>
        <DataGridTextColumn Header="Conditions" Binding="{Binding Conditions}"/>
    </DataGrid.Columns>
</DataGrid>

And the underlying code is the following:

public partial class MainWindow : Window
{
    private readonly MonsterService _monsterService;
    private readonly DatabaseService _databaseService;
    public MainWindow()
    {
        InitializeComponent();
        _monsterService = new MonsterService();
        _databaseService= new DatabaseService();
        foreach (var player in _databaseService.Players)
        {
            creatureDatagrid.Items.Add(player);
        }
        _databaseService.DoStuff();
        foreach (var monster in _databaseService.ActiveMonsters)
        {
            creatureDatagrid.Items.Add(monster);
        }
    }


}

Players and Monsters are added to the CreatureDatagrid. Players and Monsters are classes with information such as Name, HP and Speed.

Currently, I'd like to make a custom cell for "Traits". Monsters contain a list<NameValuePair> where NameValuePair contains Name and Value

The current Datagrid looks as follows: enter image description here

As you can see, the Names and Values of the traits display correctly, but the code is not really that pretty...

CodePudding user response:

You could put an ItemsControl in the CellTemplate that binds to the Traits property:

<DataGridTemplateColumn Header="Traits">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <ItemsControl ItemsSource="{Binding Traits}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal" />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Name}" ToolTip="{Binding Value}" Margin="2,0"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
  • Related