2011-01-08 89 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

相關問題