Home > Net >  How to customize the DataTemplate of ListViewItem when bound to collection
How to customize the DataTemplate of ListViewItem when bound to collection

Time:01-09

I am having trouble customizing the ListViewItems. The listview is bound to an ObservableCollection in the ViewModel and I don't have any issues with the binding without the DataTemplate of ListViewItem set. But if the ItemTemplate is set I get the following exception:

Message = "Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))"

On exploring about this exception this seems to occur for a variety of reasons and I am not able to find the cause.

Here is the View snippet:

<ListView
    Margin="12"
    DisplayMemberPath="Name"
    IsItemClickEnabled="True"
    SelectedItem="{x:Bind ViewModel.SelectedFile, Mode=TwoWay}"
    ItemsSource="{x:Bind ViewModel.Files}"
    SelectionMode="Single">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="vms:FileViewModel">
            <StackPanel Orientation="Vertical">
                <TextBlock Text="File Name" Margin="5"/>
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

I tried converting the DataTemplate into a StaticResource also to no avail. And the ViewModel snippet is:

public ObservableCollection<FileViewModel> Files { get; } = new ObservableCollection<FileViewModel>();

public async Task InitAsync()
{
    store = new PersistedStore();
    await store.InitAsync();

    foreach (var model in await store.GetAllAsync())
    {
        Files.Add(new FileViewModel(model.Id, model.OriginalPath, model.ConvertedTypes, model.FileSize));
    }
}

Using breakpoints I was also able to ensure that the exception does not occur during the addition of files to the list. It happens immediately after the InitAsync(). Tried changing all to non-async methods just to identify the issue and same case.

Any help would be highly appreciated

CodePudding user response:

I checked the DisplayMemberPath property. It makes sense that the DisplayMemberPath and the datatemplate are in conflict. When you set the DisplayMemberPath, the ListView is supposed to sets the name or path of the property that is displayed for each data item. It uses the default ListViewItem. But setting the DataTemplate will change the this.

So I will say that you can't set the DisplayMemberPath property and the DataTemplate at the same time. It will be better to just use the DataTemplate to show the property you want.

CodePudding user response:

For customization DataTemplate you can use inside it ListViewItem

<DataTemplate x:DataType="vms:FileViewModel">
     <ListViewItem Style="{StaticResource ListViewItemStyle}">
         <TextBlock Text="File Name" Margin="5"/>
     </ListViewItem>
</DataTemplate>

You can assign to Style property ListViewItemStyle and customize it.

Example ListViewItemStyle`

<Style x:Key="CoffeeListStyle" TargetType="ListViewItem">
        <Setter Property="BorderThickness" Value="0" />
        <Setter Property="HorizontalAlignment" Value="Left" />
        <Setter Property="Width" Value="140" />
        <Setter Property="Height" Value="60" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListViewItem">
                    <Grid>
                        <ContentPresenter Width="{TemplateBinding Width}" 
                                          Height="{TemplateBinding Height}" />
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal" />
                                <VisualState x:Name="PointerOver" />
                                <VisualState x:Name="Pressed" />
                                <VisualState x:Name="Selected" />
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
  • Related