0

I've been struggling for a while to get this to work.

I don't think this is a duplicate, since no other post I found had this issue or helped me solve mine, but if it is a duplicate, I apologize.

I have a UserControl that inherits from another UserControl. This child needs to display a list of items not present or needed for the other children of my base.

C#:

public partial class EntitlementUserControl : BaseUserControl
{
  public ObservableCollection<Entitlement> EntitlementCollection { get; set; } = new ObservableCollection<Entitlement>();

  public EntitlementUserControl()
  {
    InitializeComponent();
    this.DataContext = this;
    EntitlementCollection.Add(new Entitlement("Test"));
  }
}

EntitlementID here should display the "Test" entered in the constructor.

WPF:

    <ListView x:Name="entitlementList" ItemsSource="{Binding EntitlementCollection}" >
  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
      <UniformGrid Columns="5" HorizontalAlignment="Stretch"/>
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>
  <ListView.ItemTemplate>
    <DataTemplate>
      <TextBlock Text="{Binding Path=EntitlementID}"/>
    </DataTemplate>
  </ListView.ItemTemplate>
</ListView>

This doesn't work for me, I found this that explained I needed the DataContext, but even with it, it doesn't display my values correctly. An item shows up in the ListView, but it's empty and doesn't contain any text, picture below. The black is my styleresource because it's selected to show that one item is created.

Picture

However, if I change the XAML to instead have a Gridview in the listview, it displays my data, but my goal is to format data, not show a grid.

Working Xaml with Gridview:

<ListView x:Name="entitlementList" ItemsSource="{Binding EntitlementCollection}" >
  <ListView.View>
  <GridView>
    <GridViewColumn Header="ID" DisplayMemberBinding="{Binding EntitlementID}"/>
  </GridView>
  </ListView.View>
</ListView>

Working GridView

As you can see, this shows correctly the "Test" in the ID Column. However I want to be able to show the list without any columns and be able to apply the formatting I want. Any ideas why the first way isn't working?

Entitlement is just a small class containing the ID and a list of products. Entitlement:

public class Entitlement
{
  List<Product> products;

  public List<Product> Products { get => products; set => products = value; }
  public string EntitlementID { get => entitlementID; set => entitlementID = value; }

  string entitlementID;

  public void AddProduct(Product product)
  {
    Products.Add(product);
  }

  public Entitlement(string entitlementID)
  {
    products = new List<Product>();
    this.entitlementID = entitlementID;
  }

  public override string ToString()
  {
    return EntitlementID;
  }
}

Please let me know if you need more code.

Style used for ListView (Not made by me, provided for me):

<Style TargetType="{x:Type ListViewItem}"  >
<Setter Property="Template">
  <Setter.Value>
    <ControlTemplate TargetType="{x:Type ListViewItem}">
      <Border BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" CornerRadius="2"
              SnapsToDevicePixels="true">
        <Border x:Name="InnerBorder" CornerRadius="1" BorderThickness="1">
          <Grid>
            <Grid.RowDefinitions>
              <RowDefinition MinHeight="18"/>
              <RowDefinition/>
            </Grid.RowDefinitions>
            <Rectangle x:Name="UpperHighlight" Visibility="Collapsed" Fill="{StaticResource UpperReflection_Normal_BackgroundBrush}"/>
            <GridViewRowPresenter Grid.RowSpan="2" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
          </Grid>
        </Border>
      </Border>
      <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver" Value="true">
          <Setter Property="Background" Value="{StaticResource FlatButton_MouseOver_BackgroundBrush}"/>
          <Setter Property="BorderBrush" Value="{StaticResource FlatButton_MouseOver_BorderBrush}"/>
          <Setter Property="BorderBrush" TargetName="InnerBorder" Value="{StaticResource FlatButton_MouseOver_InnerBorderBrush}" />
          <Setter TargetName="UpperHighlight" Property="Visibility" Value="Visible"/>
        </Trigger>
        <!--<Trigger Property="Helpers:ItemDragState.IsUnderDragCursor" Value="True">
          <Setter Property="Background" Value="{StaticResource ListViewItem_Hover_BackgroundBrush}"/>
          <Setter Property="BorderBrush" Value="{StaticResource ListViewItem_Hover_BorderBrush}"/>
          <Setter TargetName="UpperHighlight" Property="Visibility" Value="Visible"/>
        </Trigger>-->
        <Trigger Property="IsSelected" Value="true">
          <Setter Property="Background" Value="{StaticResource ListItemSelectedFill_BackgroundBrush}"/>
          <Setter Property="BorderBrush" Value="{StaticResource ListItemSelectedFill_BorderBrush}"/>
                        <Setter Property="Foreground" Value="White" />
                        <Setter TargetName="InnerBorder" Property="BorderBrush" Value="{StaticResource ListViewItem_Selected_InnerBorderBrush}"/>
          <Setter TargetName="UpperHighlight" Property="Visibility" Value="Visible"/>
          <Setter TargetName="UpperHighlight" Property="Fill" Value="#40FFFFFF"/>
        </Trigger>
        <MultiTrigger>
          <MultiTrigger.Conditions>
            <Condition Property="IsSelected" Value="true"/>
            <Condition Property="Selector.IsSelectionActive" Value="false"/>
          </MultiTrigger.Conditions>
          <Setter Property="Background" Value="{StaticResource ListItemSelectedInactiveFill_BackgroundBrush}"/>
          <Setter Property="BorderBrush" Value="{StaticResource ListItemSelectedInactiveFill_BorderBrush}"/>
        </MultiTrigger>
        <MultiTrigger>
          <MultiTrigger.Conditions>
            <Condition Property="IsSelected" Value="true"/>
            <Condition Property="IsMouseOver" Value="true"/>
          </MultiTrigger.Conditions>
          <Setter Property="Background" Value="{StaticResource ListItemSelectedHoverFill_BackgroundBrush}"/>
          <Setter Property="BorderBrush" Value="{StaticResource ListItemSelectedHoverFill_BorderBrush}"/>
        </MultiTrigger>
        <Trigger Property="IsEnabled" Value="false">
          <Setter Property="Foreground" Value="{StaticResource {x:Static SystemColors.GrayTextBrushKey}}"/>
        </Trigger>
      </ControlTemplate.Triggers>
    </ControlTemplate>
  </Setter.Value>
</Setter>

  • A `UserControl` should not have its own `DataContext` as in your code. A `UserControl` should be reusable and thus should inherit the data context from its parent or get the data context explicitly from its parent. – dymanoid Nov 30 '18 at 12:58
  • I wasn't sure if it was supposed to get it's own `DataContext` but I tried it because the post I linked to said it would help, so included it to avoid any "Try setting DataContext" comments. – Mr. Mansson Nov 30 '18 at 13:01
  • Now I feel dumb. The Style was causing the issue. I'll post it anyway to try and figure out why, but deleting the style solved the issue. – Mr. Mansson Nov 30 '18 at 13:09

2 Answers2

0

It seems the Style for the ListView is what caused the issue. Removing the Style correctly displays the data:

No Style

I am not sure what part of the Style is blocking the display however. If this is not applicable for anyone else, should I remove the question?

0

Your ListViewItem's style uses a GridViewRowPresenter. Without a GridView, you indeed won't see any content in your cells.

Use a ContentPresenter instead:

<ContentPresenter Grid.RowSpan="2" 
    VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
    SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
dymanoid
  • 14,771
  • 4
  • 36
  • 64