2011-01-08 77 views
1

我正在写一个自定义控件,它是一个ListView,它在ListView中的每个项目上都有一个CheckBox以指示该项目被选中。我可以用下面的XAML来做到这一点。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> 

但是我试图尝试一个更多的功能。 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时遇到问题,以便我可以为其绑定一个值集合,并且在加载控件时,将使用具有与SelectedValues相对应的值的项目检查CheckBox。

我已经考虑使用PropertyChangedCallBack事件,但不能完全弄清楚如何编写这个来实现我的目标。

我也不确定我如何找到正确的ListViewItem将其设置为Selected。

最后,如果我能找到ListViewItem并将其设置为Selected,那么每次设置ListViewItem为Selected时,都不会激发我的SelectionChanged事件吗?

回答

1
+0

我能得到这个使用附加属性的工作。差不多。我为ListBox(也适用于ListViews)创建了名为SelectedValues的附加属性。一切工作都很好。加载控件时,存储在绑定到我的属性的一个集合中的ID会正确选择ListView控件中的项目。当我在控件中进行更改时,源绑定到我附加的属性更新。但是,当我从后面的代码更新源时,我的控件仍然不会自动更新。我不确定我做错了什么。 – Ristogod 2011-01-09 23:45:59

相关问题