Reputation: 686
I wrote a custom control to displays items from an ItemsSource at calculated positions.
Generic.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Control="clr-namespace:MyControls.Control">
<Style TargetType="{x:Type Control:MyControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Control:MyControl}">
<Border x:Name="DrawingArea"
BorderThickness="{TemplateBinding Border.BorderThickness}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
Padding="{TemplateBinding Control.Padding}"
Background="{TemplateBinding Panel.Background}"
SnapsToDevicePixels="true">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Canvas IsItemsHost="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ClipToBounds="true" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
...
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
MyControl.cs
public class MyControl : MultiSelector, INotifyPropertyChanged
{
private bool _layoutHandlingDone = false;
private Border _drawingArea;
private Border DrawingArea
{
get { return _drawingArea ?? (_drawingArea = (Border) Template.FindName("DrawingArea", this)); }
}
static MyControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyControl), new FrameworkPropertyMetadata(typeof(MyControl)));
}
protected override Size MeasureOverride(Size aviableSize) { ... }
protected override Size ArrangeOverride(Size finalSize) { ... }
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
if (Template != null && _layoutHandlingDone == false)
{
_layoutHandlingDone = true;
ItemContainerGenerator.StatusChanged += (sender, args) =>
{
if(ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
InvalidateMeasure();
};
DrawingArea.SizeChanged += (sender, args) => UpdateLayout();
}
}
}
Layouting and drawing the items works very well. Now I want the items to be selectable. For this I derived my control form MultiSelector, but it seems that this isn't enough.
What functionality does the MultiSelector provide and how should I use it in my control?
Upvotes: 0
Views: 578
Reputation: 128098
I strongly suggest to separate things here. Managing a collection of items and arranging them in a container control are two distinct concerns, and ItemsControl provides support for both.
Instead of overriding MeasureOverride and ArrangeOverride, you should write your specialized Panel class (and override MeasureOverride and ArrangeOverride there) and use that class in the ItemsPanel template of your ItemsControl.
You could then easily derive from ListBox instead of MultiSelector and would get all the selection functionality for free.
Upvotes: 2