2012-12-14 3 views
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 и как ее использовать в моем управлении?

ответ

1

Настоятельно предлагаю отделить вещи здесь. Управление набором элементов и организация их в контроле контейнера - две разные проблемы, а ItemsControl обеспечивает поддержку обоих.

Вместо перекрывая MeasureOverride и ArrangeOverride, вы должны написать свой специализированный Panel класс (и переопределить MeasureOverride и ArrangeOverride есть) и использовать этот класс в ItemsPanel шаблоне вашего ItemsControl.

После этого вы можете легко получить из списка ListBox вместо MultiSelector и получить все функции выбора бесплатно.

+0

Производящая форму ListBox сделала это. Благодарю. Но я понял, что вы правы: я могу извлечь из Panel вместо ListBox. Поместите MyPanel в свойство ItemsPanel ItmesControl, ListBox или то, что когда-либо выбирается. И получите ту же функциональность? –

+0

Точно. Это то, для чего предназначалось свойство 'ItemsPanel'. Используйте ListBox со специализированной панелью. Я делаю это, например, для упорядочивания элементов на контроле карты в географических точках. Элементы карты управляются стандартным ListBox, но шаблон ItemsPanel определяет специализированную «MapPanel», которая выполняет все необходимые вычисления для фактического размещения элементов. – Clemens

Смежные вопросы