Dynamically display objects according to the size WPF

329 views Asked by At

I have to display a ListView of objects. These objects are structured as a Grid with two columns. The first column contains the view of the Element, the second one, contains a collection of arrows (in a vertical way).

I created a control "Arrow" to display it in the second column like the following image:

enter image description here

My problem is: how can I put dynamically the right number of arrows in the second column, according to the Height of the object put in the first Column.

Which Structure to use to ensure that the second column will be flexible ? Grid, StackPanel or something else ?

Please consider that the arrows have a fixed size.

1

There are 1 answers

0
AlSki On BEST ANSWER

All you really need to do is generate a list, one item for each arrow, based on the space you need to fill. Lets start with a converter

public void MakeArrowListConverter : IValueConverter
{
  public double ArrowHeight {get;set;}

  public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  {
     var verticalSpace = (double) value;
     int numberOfArrows = (int)(verticalSpace/ArrowHeight);
     return Enumerable.Range(0, numberOfArrows);
  }
}

This needs to convert sopmething which we have the height of, in this case I'd just use a ContentPresenter and Bind that to your view.

<ContentPresenter x:Name="content" Content="{Binding}"/>

So then we simply need to take the height and convert it into your list

<xxx.Resources>
  <convertors:MakeArrowListConverter x:Key="makeArrowListConverter" /> 
</xxx.Resources>

<ListBox ItemsSource="{Binding ElementName=content, Path=ActualHeight, Converter={StaticResource makeArrowListConverter}}">
  <ItemTemplate>
    <DataTemplate>
      <!-- Image or Shape, this is your red arrow-->
      <YourArrow/>
    </DataTemplate>
  </ItemTemplate>
</ListBox>

In fact we can put these two elements into another into a dataTemplate to convert each item of your data into its displayed form when its used in a list

<DataTemplate DataType="{x:Type MyView}">
  <!--This is your blue box-->
  <StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
    <ContentPresenter x:Name="content" Content="{Binding}"/>
    <ListBox ItemsSource="{Binding ElementName=content, Path=ActualHeight, Converter={StaticResource makeArrowListConverter}}">
      <ItemTemplate>
        <DataTemplate>
          <!-- Image or Shape, this is your red arrow-->
          <YourArrow/>
        </DataTemplate>
      </ItemTemplate>
    </ListBox>
  </StackPanel>
</DataTemplate>

<!-- And this is your orange box-->
<ListBox ItemsSource="{Binding YourListOfViews}"/>