简体   繁体   中英

Determine what cell is calling SelectTemplate in GridViewRowPresenter

I'm attempting to use the GridViewRowPresenter to be the ItemsPresenter in a TreeListView. The catch is I want to be able to determine the DataTemplates for each cell in the grid at run time. I've been using a DataTemplateSelector to choose the template but in order to pick the right template for the right column I need to determine which column is the current column in the call to SelectTemplate. What I've been doing is assuming that SelectTemplate gets called sequentially. In other words if I have 4 columns the first call would be for the first column the second for the next and so on. So I could have a list of DataTemplates in the ContentTemplateSelector and simply return the appropriate template, after 4 calls reset the index and return the first template again.

This mostly works, however, I have found that after a certain number of rows I can no longer count on the calls to SelectTemplate to come in a consistent pattern.

Does anyone have any advise as to how to achieve this? Is there a way to determine the Cell in question in the SelectTemplate call?

I have been playing with WPF DataGrid and I needed to do something similar. I tried to do most of it in XAML but you could certainly do it in the code-behind as well.

In my case, I wanted to choose a template for each cell in a DataGrid based on information within the data being displayed. My DataGrid shows chunks of data that are all put together to create a Serial Command. I wanted the ability to select the Edit / Display template based on the type of data each "SerialBlock" contains.

public class ColumnTemplateSelector : DataTemplateSelector
{
    public DataTemplate ColorTemplate { get; set; }
    public DataTemplate RawBytesTemplate { get; set; }
    public DataTemplate AddressTemplate { get; set; }
    public DataTemplate CommandTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {

        SerialBlock command = item as SerialBlock;
        if (null != command)
        {
            switch (command.BlockType)
            {
                case EnumBlockType.Address:
                    return AddressTemplate;
                case EnumBlockType.Color:
                    return ColorTemplate;
                case EnumBlockType.Command:
                    return CommandTemplate;
                case EnumBlockType.RawBytes:
                    return RawBytesTemplate;

            }
        }
        return base.SelectTemplate(item, container);

    }

}

In the XAML, I use the following to create a column... (I have several more as well)

<DataGridTemplateColumn>
    <DataGridTemplateColumn.CellTemplateSelector>
        <src:ColumnTemplateSelector 
            ColorTemplate="{StaticResource ColorEditTemplate}"
            AddressTemplate="{StaticResource AddressEditTemplate}"
            RawBytesTemplate="{StaticResource RawBytesEditTemplate}"
            CommandTemplate="{StaticResource CommandEditTemplate}">
        </src:ColumnTemplateSelector>
    </DataGridTemplateColumn.CellTemplateSelector>
</DataGridTemplateColumn>

Then I create the Templates like this... (of course, I have have several more)

    <DataTemplate x:Key="AddressTemplate">
        <Border Padding="3" Background="Green">
            <TextBlock Text="{Binding Path=BlockText}" />
        </Border>
    </DataTemplate>
    <DataTemplate x:Key="AddressEditTemplate">
        <Border Padding="3" Background="Green">
            <TextBlock Text="{Binding Path=BlockText}" />
        </Border>
    </DataTemplate>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM