-4

I have some defined XAML that looks like

<ListView ItemsSource="{Binding ConfigItems,Mode=OneWay}" Margin="5">
    <ListView.ItemContainerStyle> 
        <Style TargetType="ListViewItem"> 
            <Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter> 
        </Style> 
    </ListView.ItemContainerStyle>
    <ItemsControl
        ItemsSource="{Binding}"
        ItemTemplateSelector="{StaticResource ConfigItemDataSelector}"/>
</ListView>

Now I realize that this isn't how it should be but that is the source of the question. As is I get an exception that indicates the ItemsSource should be empty before using it. From a question asked 12 years ago I see that this exception is raised when Items and ItemsSource properties are being used at the same time. So I set out to use one or the other. But I get this error when I define it like above or when I leave ItemsSource out altogether. When I try to use Items I get an error at compile time that indicates the list has to have a setter. In case there is some confusion the ConfigItemDataSelector looks like basically returns a DataTemplate depending on which view model is being used. But I think looking at the selector is a distraction from the problem.

public sealed class ConfigItemDataSelector : DataTemplateSelector
{
    public DataTemplate MeasurementDataTemplate { get; set; }
. . .
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item is MeasurementConfigItemViewModel)
        {
            return MeasurementDataTemplate;
        }
        else if (item is LEDFeedbackConfigItemViewModel)
        {
            return LEDFeedbackDataTemplate;
        }
. . . 
        return null;
    }
}

So how should the ListView use the ItemsControl?

Kevin Burton
  • 2,032
  • 4
  • 26
  • 43
  • Putting a single ItemsControl into a ListView is pointless. A ListView is already an ItemsControl, i.e. the ListView class is derived from the ItemsControl class. Not sure which problem exactly you are trying to solve, but it seems you should simply set the ItemsSource and ItemTemplateSelector properties of the ListView. And perhaps use the simpler ListBox instead of ListView - unless you actually set the ListView's View property. – Clemens May 04 '21 at 07:20
  • I did not know that thanks for the info. If this was the "simpler" `ListBox` then I would need an `ItemsControl`? – Kevin Burton May 05 '21 at 20:28
  • No, of course not. You should take a look at [the documentation](https://learn.microsoft.com/en-us/dotnet/api/system.windows.controls.listview?view=net-5.0), the inheritance chain is ItemsControl -> Selector -> ListBox -> ListView. – Clemens May 05 '21 at 20:38

2 Answers2

0

You can not put ItemsControl in ListView.Items

Try this

    <ListView ItemsSource="{Binding ConfigItems,Mode=OneWay}" Margin="5">
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
            </Style>
        </ListView.ItemContainerStyle>
        <ListView.ItemTemplate>
            <DataTemplate>
                <ItemsControl ItemsSource="{Binding}"
                              ItemTemplateSelector="{StaticResource ConfigItemDataSelector}"/>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

You can see source code in referencesource.microsoft.com

The ItemsControl have DefaultPropertyAttribute("Items"), so if you do not declare what property you used in xaml, it will set to ListView.Items be equal

<ListView ItemsSource="{Binding ConfigItems,Mode=OneWay}" Margin="5">
    <ListView.ItemContainerStyle> 
        <Style TargetType="ListViewItem"> 
            <Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter> 
        </Style> 
    </ListView.ItemContainerStyle>
    <ListView.Items>
      <ItemsControl
        ItemsSource="{Binding}"
        ItemTemplateSelector="{StaticResource ConfigItemDataSelector}"/>
    </ListView.Items>  
</ListView>

And throw exception say "ItemsSource should be empty before using it"

Allen Hu
  • 141
  • 6
-2

I found through trial and error that the following works

<ListView Margin="5">
    <ListView.ItemContainerStyle> 
        <Style TargetType="ListViewItem"> 
            <Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter> 
        </Style> 
    </ListView.ItemContainerStyle>
    <ItemsControl
        ItemsSource="{Binding ConfigItems}"
        ItemTemplateSelector="{StaticResource ConfigItemDataSelector}"/>
</ListView>

Basically taking the ItemsSource property from the ListView and moving it to the ItemsControl.

Kevin Burton
  • 2,032
  • 4
  • 26
  • 43