2011-01-08 3 views
1

Ich schreibe ein benutzerdefiniertes Steuerelement, das ein ListView ist, das über ein Kontrolle-Kästchen für jedes Element in dem ListView verfügt, um anzuzeigen, dass Element ausgewählt ist. Ich konnte dies mit dem folgenden XAML tun.CheckBox ListView SelectedValues ​​Abhängigkeitseigenschaft Bindung

<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> 

Ich versuche jedoch, eine weitere Funktion zu versuchen. Das ListView verfügt über eine SelectedItems DependencyProperty, die eine Auflistung der Elemente zurückgibt, die überprüft werden. Ich muss jedoch eine SelectedValues ​​DependencyProperty implementieren. Ich implementiere auch eine SelectedValuesPath DependencyProperty. Mit dem SelectedValuesPath gebe ich den Pfad an, in dem die Werte für jedes ausgewählte Element gefunden werden. Wenn also meine Artikel eine ID-Eigenschaft haben, kann ich mit der SelectedValuesPath-Eigenschaft "ID" angeben. Die SelectedValues-Eigenschaft würde dann eine Sammlung von ID-Werten zurückgeben. Ich habe diese Arbeits auch mit diesem Code in dem 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; 
     } 
    } 
} 

Mein Problem ist, dass meine Bindung nur einen Weg, jetzt funktioniert. Ich habe Probleme, herauszufinden, wie meine SelectedValues ​​DependencyProperty implementiert wird, damit ich eine Sammlung von Werten an sie binden kann, und wenn das Steuerelement geladen wird, werden die CheckBoxen mit Elementen überprüft, deren Werte den SelectedValues ​​entsprechen.

Ich habe überlegt, das PropertyChangedCallBack-Ereignis zu verwenden, kann aber nicht genau herausfinden, wie ich das schreiben könnte, um mein Ziel zu erreichen.

Ich bin mir auch nicht sicher, wie ich das richtige ListViewItem finde, um es als Ausgewählt zu setzen.

Und schließlich, wenn ich das ListViewItem finden und es als Selected festlegen kann, löst das nicht mein SelectionChanged-Ereignis jedes Mal, wenn ich ein ListViewItem auf Selected gesetzt habe?

Antwort

1
+0

Ich konnte dies eine angebaute Eigenschaft zur Arbeit kommen mit. Naja fast. Ich habe eine angehängte Eigenschaft für ListBox (funktioniert auch für ListViews) namens SelectedValues. Alles funktioniert super bei Belastung. Wenn das Steuerelement geladen wird, wählen IDs, die in einer Sammlung gespeichert sind, die an meine Eigenschaft gebunden ist, die Elemente im ListView-Steuerelement aus. Und wenn ich Änderungen im Steuerelement vornehme, wird die an meine angehängte Eigenschaft gebundene Quelle aktualisiert. Wenn ich jedoch die Quelle aus dem Code dahinter aktualisiere, wird mein Steuerelement immer noch nicht automatisch aktualisiert. Ich bin mir nicht sicher, was ich falsch mache. – Ristogod