2011-01-08 13 views
1

ListView内の各項目のCheckBoxを持つカスタムコントロールを作成して、その項目が選択されていることを示します。私は次のXAMLでこれを行うことができました。CheckBox ListView SelectedValues DependencyProperty Binding

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

ただし、もう1つの機能を試してみます。 ListViewには、チェックされる項目のコレクションを返すSelectedItems DependencyPropertyがあります。しかし、私はSelectedValues DependencyPropertyを実装する必要があります。また、SelectedValuesPath DependencyPropertyを実装しています。 SelectedValuesPathを使用して、選択した各アイテムの値が見つかるパスを指定します。したがって、アイテムにIDプロパティがある場合は、SelectedValuesPathプロパティ "ID"を使用して指定できます。 SelectedValuesプロパティは、ID値のコレクションを返します。私はこの作業も、コードビハインドでこのコードを使用しています

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

私の問題は私のバインディングだけ今の一つの方法を動作することです。私は、SelectedValues DependencyPropertyを実装する方法を見つけようとしているので、値のコレクションをバインドすることができ、コントロールがロードされると、CheckBoxesはSelectedValuesに対応する値を持つ項目でチェックされます。

私はPropertyChangedCallBackイベントの使用を検討しましたが、目標を達成するためにどのように書き込むことができるのか分かりません。

正しいListViewItemがどのようにSelectedに設定されているかわかりません。

最後に、ListViewItemを見つけてSelectedに設定すると、ListViewItemをSelectedに設定するたびにSelectionChangedイベントが発生しませんか?

答えて

1
+0

私は、これは添付プロパティを使用して仕事を得ることができました。よくほとんど。私はSelectedValuesと呼ばれるListBox(ListViewsでも動作します)の添付プロパティを作成しました。すべてが負荷の上で動作します。コントロールが読み込まれると、myプロパティにバインドされた1つのコレクションに格納されているIDによって、ListViewコントロールのアイテムが適切に選択されます。そして、私がコントロールを変更すると、ソースは、添付されたプロパティの更新にバインドされます。しかし、ソースコードを後ろから更新すると、コントロールは自動的に更新されません。私は何が間違っているのか分かりません。 – Ristogod

関連する問題