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>