Reputation:
I have a list of objects with X
,Y
properties. I want to put the collection into ItemsControl
and position each item according to its x and y.
I don't know the maximum of X or Y.
I tried to use Canvas
as ItemsControl.ItemsPanel, but Canvas doesn't change its size based on its children. Thus ScrollViewer cannot scroll ItemsControl.
I checked How to Visible ScrollBar In Items Panel With Canvas as ItemsPaneltemplate. The first solution is to use Grid and set Margin. However, Thickness.X and Thickness.Y are not dependency properties and not bindable. The second solution is OK but involves code-behind. The last solution should also work but writing a new class is laborious.
How to position items in ItemsControl and enable scroll? What solution do you prefer?
Upvotes: 2
Views: 438
Reputation: 13302
Though Thickness.X and Thickness.Y are not dependency properties, Margin is. You just need to define a ValueConverter that accepts your object containing X and Y values, or a MultiValueConvert that accepts the X and Y values. Both implementations would return a Thickness.
<YourElement.Margin>
<MultiBinding Converter="{StaticResource myMarginConverter}">
<Binding Path="X"/>
<Binding Path="Y"/>
</MultiBinding>
</YourElement.Margin>
.
public class NameConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
//Validate parameters...
Thickness margin = new Margin(values[0], values[1], 0d, 0d);
return margin;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
//Validate parameters...
double x = ((Thickness)value).Left;
double y = ((Thickness)value).Top;
return new object[]{x, y};
}
}
I haven't tested this code but you get the picture. As far as which approach is better, using a Canvas sounds like more of a control designed for your intended purpose. However, it depends on the details of what you're trying to do. I believe canvas has potential for greater efficiency with virtualization if you're expecting a lot of points. If they don't need to be interactive, you could also just draw them to a bitmap image.
Upvotes: 0