0

計算された位置にItemsSourceからのアイテムを表示するカスタムコントロールを作成しました。

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();
        }
    }   
}

アイテムのレイアウトと描画は非常にうまく機能します。今、私はアイテムを選択可能にしたいです。このために、コントロールフォームMultiSelectorを派生させましたが、これでは不十分なようです。

MultiSelectorはどのような機能を提供し、コントロールでどのように使用する必要がありますか?

4

1 に答える 1

1

ここで物事を分けることを強くお勧めします。アイテムのコレクションを管理し、それらをコンテナーコントロールに配置することは、2つの明確な懸念事項であり、ItemsControlは両方のサポートを提供します。

MeasureOverrideとArrangeOverrideをオーバーライドする代わりに、専用のPanelクラスを記述して(そしてそこでMeasureOverrideとArrangeOverrideをオーバーライドして)、ItemsControlのItemsPanelテンプレートでそのクラスを使用する必要があります。

そうすれば、MultiSelectorの代わりにListBoxから簡単に派生でき、すべての選択機能を無料で利用できます。

于 2012-12-14T11:10:11.680 に答える