2011-01-08 4 views
1

J'écris un contrôle personnalisé qui est un ListView qui a un CheckBox sur chaque élément dans le ListView pour indiquer que cet élément est sélectionné. J'ai été capable de le faire avec le XAML suivant.CheckBox ListView SelectedValues ​​DependencyProperty

<ListView x:Class="CheckedListViewSample.CheckBoxListView" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d"> 
    <ListView.Style> 
     <Style TargetType="{x:Type ListView}"> 
      <Setter Property="SelectionMode" Value="Multiple" /> 
      <Style.Resources> 
       <Style TargetType="ListViewItem"> 
        <Setter Property="Template"> 
         <Setter.Value> 
          <ControlTemplate TargetType="ListViewItem"> 
           <Border BorderThickness="{TemplateBinding Border.BorderThickness}" 
             Padding="{TemplateBinding Control.Padding}" 
             BorderBrush="{TemplateBinding Border.BorderBrush}" 
             Background="{TemplateBinding Panel.Background}" 
             SnapsToDevicePixels="True"> 
            <CheckBox IsChecked="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}}"> 
             <CheckBox.Content> 
              <ContentPresenter Content="{TemplateBinding ContentControl.Content}" 
                   ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" 
                   HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}" 
                   VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" 
                   SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" /> 
             </CheckBox.Content> 
            </CheckBox> 
           </Border> 
          </ControlTemplate> 
         </Setter.Value> 
        </Setter> 
       </Style> 
      </Style.Resources> 
     </Style> 
    </ListView.Style> 
</ListView> 

Cependant j'essaye d'essayer une caractéristique plus. Le ListView a un SelectedItems DependencyProperty qui retourne une collection des éléments qui sont vérifiés. Cependant, j'ai besoin d'implémenter une SelectedValues ​​DependencyProperty. J'applique également un SelectedValuesPath DependencyProperty. En utilisant SelectedValuesPath, j'indique le chemin où les valeurs sont trouvées pour chaque élément sélectionné. Donc, si mes éléments ont une propriété ID, je peux spécifier en utilisant la propriété SelectedValuesPath "ID". La propriété SelectedValues ​​retournera alors une collection de valeurs d'ID. Je possède ce travail également en utilisant ce code dans le code-behind:

using System.Windows; 
using System.Windows.Controls; 
using System.ComponentModel; 
using System.Collections; 
using System.Collections.Generic; 

namespace CheckedListViewSample 
{ 
    /// <summary> 
    /// Interaction logic for CheckBoxListView.xaml 
    /// </summary> 
    public partial class CheckBoxListView : ListView 
    { 
     public static DependencyProperty SelectedValuesPathProperty = 
      DependencyProperty.Register("SelectedValuesPath", 
      typeof(string), 
      typeof(CheckBoxListView), 
      new PropertyMetadata(string.Empty, null)); 

     public static DependencyProperty SelectedValuesProperty = 
      DependencyProperty.Register("SelectedValues", 
      typeof(IList), 
      typeof(CheckBoxListView), 
      new PropertyMetadata(new List<object>(), null)); 

     [Category("Appearance")] 
     [Localizability(LocalizationCategory.NeverLocalize)] 
     [Bindable(true)] 
     public string SelectedValuesPath 
     { 
      get 
      { 
       return ((string)(base.GetValue(CheckBoxListView.SelectedValuesPathProperty))); 
      } 
      set 
      { 
       base.SetValue(CheckBoxListView.SelectedValuesPathProperty, value); 
      } 
     } 

     [Bindable(true)] 
     [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
     [Category("Appearance")] 
     public IList SelectedValues 
     { 
      get 
      { 
       return ((IList)(base.GetValue(CheckBoxListView.SelectedValuesPathProperty))); 
      } 
      set 
      { 
       base.SetValue(CheckBoxListView.SelectedValuesPathProperty, value); 
      } 
     } 

     public CheckBoxListView() 
      : base() 
     { 
      InitializeComponent(); 
      base.SelectionChanged += new SelectionChangedEventHandler(CheckBoxListView_SelectionChanged);  
     } 

     private void CheckBoxListView_SelectionChanged(object sender, SelectionChangedEventArgs e) 
     { 
      List<object> values = new List<object>(); 

      foreach (var item in SelectedItems) 
      { 
       if (string.IsNullOrWhiteSpace(SelectedValuesPath)) 
       { 
        values.Add(item); 
       } 
       else 
       { 
        try 
        { 
         values.Add(item.GetType().GetProperty(SelectedValuesPath).GetValue(item, null)); 
        } 
        catch { } 
       } 
      } 

      base.SetValue(CheckBoxListView.SelectedValuesProperty, values); 

      e.Handled = true; 
     } 
    } 
} 

Mon problème est que ma fixation ne fonctionne que dans un sens en ce moment. Je n'arrive pas à essayer de comprendre comment implémenter ma propriété DependencyProperty SelectedValues ​​afin que je puisse lier une collection de valeurs, et lorsque le contrôle est chargé, les CheckBox sont vérifiés avec des éléments qui ont des valeurs qui correspondent aux SelectedValues.

J'ai envisagé d'utiliser l'événement PropertyChangedCallBack, mais je n'arrive pas à comprendre comment je pourrais écrire cela pour atteindre mon objectif.

Je ne sais pas non plus comment je trouve le ListViewItem correct pour le définir comme sélectionné. Et enfin, si je peux trouver le ListViewItem et le configurer pour être sélectionné, cela ne déclenchera-t-il pas mon événement SelectionChanged chaque fois que je définirai un ListViewItem à sélectionner?

Répondre

1
+0

j'ai pu obtenir que cela fonctionne en utilisant une propriété attachée. Eh bien presque. J'ai fait une propriété attachée pour ListBox (fonctionne aussi pour ListViews) appelé SelectedValues. Tout fonctionne très bien en charge. Lorsque le contrôle est chargé, les ID stockés dans une collection liée à ma propriété sélectionnent correctement les éléments dans le contrôle ListView. Et quand je fais des changements dans le contrôle, la source liée à mes mises à jour de propriété attachées. Toutefois, lorsque je mets à jour la source à partir du code derrière, mon contrôle ne se met toujours pas à jour automatiquement. Je ne suis pas sûr de ce que je fais mal. – Ristogod