I did it via the converter that calculate the index of added element.
It works one way only. If you delete items somehow or collection changing you shoud to use thomething else.
And you shoud to create separate converter for every collection which elements you need to be indexed.
public class LineMultiplierConverter : IValueConverter
{
private int m_lineIndex = 0;
Line m_curentLine = null;
/// <summary>
/// Base value that will be multiplied
/// </summary>
public double BaseValue { get; set; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var line = value as Line;
if (line == null)
return BaseValue;
bool newLine = line != m_curentLine; //check the reference because this method will called twice on one element by my binding
if (newLine)
{
m_lineIndex++;
m_curentLine = line;
}
return BaseValue * m_lineIndex;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
I use it in xaml this way
<UserControl.Resources>
<sys:Double x:Key="BusinessRowHeight">22</sys:Double>
<local:LineMultiplierConverter x:Key="LineXConverter" BaseValue="{StaticResource BusinessRowHeight}" />
</UserControl.Resources>
<ItemsControl Grid.Row="1" ItemsSource="{Binding CarBusiness}" Margin="0 5 0 0">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Line StrokeThickness="1" Stroke="LightGray"
X1="0"
Y1="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource LineXConverter}}"
X2="{Binding RelativeSource={RelativeSource AncestorType=ItemsControl, Mode=FindAncestor}, Path=ActualWidth}"
Y2="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource LineXConverter}}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
This draws for me a lines for every element in collection with BaseValue offset for X coordinate.