2013-02-12 5 views
1

Я написал множественного выбора поведения, основанного на этой должности: WPF TreeView with Multiple SelectionWPF TreeView MultiSelect Поведение

Однако мое поведение does't, кажется, работают как expected..Can вы помочь?

Ниже мой XAML код:

<Window x:Class="TreeView.Spike.MainWindow" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Spike="clr-namespace:TreeView.Spike" 
      Title="MainWindow" Height="350" Width="525"> 
     <Window.Resources> 
     </Window.Resources> 
     <Grid> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width=".5*"/> 
       <ColumnDefinition Width=".5*"/> 
      </Grid.ColumnDefinitions> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="*"></RowDefinition> 
       <RowDefinition Height="40"></RowDefinition> 
      </Grid.RowDefinitions> 

      <TreeView ItemsSource="{Binding Nodes}" Grid.Row="0" x:Name="treeView" Grid.Column="0"> 
       <TreeView.ItemTemplate> 
        <HierarchicalDataTemplate ItemsSource="{Binding Nodes}"> 
         <StackPanel Orientation="Horizontal"> 
          <TextBlock Text="{Binding Name}">     
         </TextBlock> 
         </StackPanel> 
        </HierarchicalDataTemplate> 
       </TreeView.ItemTemplate> 
       <TreeView.ContextMenu> 
        <ContextMenu> 
         <MenuItem Header="Add"></MenuItem> 
         <MenuItem Header="Delete"></MenuItem> 
        </ContextMenu> 
       </TreeView.ContextMenu> 
       <i:Interaction.Behaviors> 
    <Spike:MultipleItemSelectionAttachedBehavior AllSelectedItems="{Binding Path=AllSelectedNodes}"/> 
</i:Interaction.Behaviors> 
      </TreeView> 

     </Grid> 
    </Window> 

Мой прикрепленному поведению:

public class MultipleItemSelectionAttachedBehavior:Behavior<System.Windows.Controls.TreeView> 
     { 
      public static DependencyProperty AllSelectedItemsProperty = 
      DependencyProperty.RegisterAttached("AllSelectedItems", typeof(object), typeof(MultipleItemSelectionAttachedBehavior), 
     new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.Inherits)); 

      private static readonly PropertyInfo IsSelectionChangeActiveProperty = typeof(System.Windows.Controls.TreeView).GetProperty("IsSelectionChangeActive", 
       BindingFlags.NonPublic | BindingFlags.Instance); 

      public object AllSelectedItems 
      { 
       get 
       { 
        return (object)GetValue(AllSelectedItemsProperty); 
       } 
       set 
       { 
        SetValue(AllSelectedItemsProperty, value); 
       } 
      } 

      public static bool GetAllSelectedItems(DependencyObject obj) 
      { 
       return (bool)obj.GetValue(AllSelectedItemsProperty); 
      } 

      public static void SetAllSelectedItems(DependencyObject obj, bool value) 
      { 
       obj.SetValue(AllSelectedItemsProperty, value); 
      } 

      protected override void OnAttached() 
      { 
       base.OnAttached(); 
       AssociatedObject.SelectedItemChanged += AssociatedObject_SelectedItemChanged; 
      } 

      protected override void OnDetaching() 
      { 
       base.OnDetaching(); 
       AssociatedObject.SelectedItemChanged -= AssociatedObject_SelectedItemChanged; 
      } 

      void AssociatedObject_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e) 
      { 
       if (IsSelectionChangeActiveProperty == null) return; 

       var selectedItems = new List<Node>(); 

       var treeViewItem = AssociatedObject.SelectedItem as Node; 
       if (treeViewItem == null) return; 

       // allow multiple selection 
       // when control key is pressed 
       if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) 
       { 
        var isSelectionChangeActive = IsSelectionChangeActiveProperty.GetValue(AssociatedObject, null); 

        IsSelectionChangeActiveProperty.SetValue(AssociatedObject, true, null); 
        selectedItems.ForEach(item => item.IsSelected = true); 

        IsSelectionChangeActiveProperty.SetValue(AssociatedObject, isSelectionChangeActive, null); 
       } 
       else 
       { 
        // deselect all selected items except the current one 
        selectedItems.ForEach(item => item.IsSelected = (item == treeViewItem)); 
        selectedItems.Clear(); 
       } 

       if (!selectedItems.Contains(treeViewItem)) 
       { 
        selectedItems.Add(treeViewItem); 
       } 
       else 
       { 
        // deselect if already selected 
        treeViewItem.IsSelected = false; 
        selectedItems.Remove(treeViewItem); 
       } 

       AllSelectedItems = selectedItems; 
      } 
     } 

..и мой ViewModel

public class ViewModel :NotificationObject 
     { 
      public ViewModel() 
      { 
       AllSelectedNodes = new ObservableCollection<Node>(); 
      } 
    private ObservableCollection<Node> _allSelectedNodes; 
      public ObservableCollection<Node> AllSelectedNodes 
      { 
       get { return _allSelectedNodes; } 
       set 
       { 
        _allSelectedNodes = value; 
        RaisePropertyChanged(() => AllSelectedNodes); 
       } 
      } 
    } 

Моя модель:

public class Node:NotificationObject 
     { 

      private string _name; 
      public string Name 
      { 
       get { return _name; } 
       set 
       { 
        _name = value; 
        RaisePropertyChanged(() => Name); 
       } 
      } 




      private bool _isExpanded = true; 
      public bool IsExpanded 
      { 
       get { return _isExpanded; } 
       set 
       { 
        _isExpanded = value; 
        RaisePropertyChanged(() => IsExpanded); 
       } 
      } 

      private bool _isSelected; 

      public bool IsSelected 
      { 
       get { return _isSelected; } 
       set 
       { 
        _isSelected = value; 
        RaisePropertyChanged(() => IsSelected); 

       } 
      } 

      private ObservableCollection<Node> _nodes; 
      public ObservableCollection<Node> Nodes 
      { 
       get { return _nodes; } 
       set 
       { 
        _nodes = value; 
        RaisePropertyChanged(() => Nodes); 
       } 
      } 

      public static IList<Node> Create() 
      { 
       return new List<Node>() 
          { 
           new Node() 
            { 
             Name = "Activity", 
             Nodes = new ObservableCollection<Node>() 
                { 
                 new Node() {Name = "Company",Nodes = new ObservableCollection<Node>(){ new Node() {Name = "Company1",Existing = false}}}, 
                 new Node() {Name = "Strategy",Nodes = new ObservableCollection<Node>(){ new Node() {Name = "Strategy1"}}}, 
                  new Node() {Name = "Vehicle",Nodes = new ObservableCollection<Node>(){ new Node() {Name = "Vehicle1",Existing = false}}} 
                } 
            } 
          }; 
      } 
     } 

..и мой инициализации Clode:

public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      var viewModel = new ViewModel(); 
      this.DataContext = viewModel; 
      viewModel.Nodes = new ObservableCollection<Node>(Node.Create()); 

     } 
} 

Вопрос заключается в том, что она по-прежнему выбирает только один, а он должен выбрать несколько, удерживая клавишу возврата управления.

ответ

-3

вам нужно добавить режим выбора свойство TreeView как этот

SelectionMode="Multiple" 
0

вам не хватает связыванию собственности IsSelected:

<TreeView.ItemContainerStyle> 
      <Style TargetType="TreeViewItem"> 
       <Setter Property="IsSelected" Value="{Binding IsSelected}" /> 
      </Style> 
    </TreeView.ItemContainerStyle> 
0

В AssociatedObject_SelectedItemChanged, как это отсчитывать SelectedItems когда-либо что-либо, кроме ноль, когда вы просто создаете экземпляр, или 1, когда вы добавите treeViewItem к нему чуть позже? Попробуйте установить его в свойство AllSelectedItems. Кроме того, не должно ли свойство AllSelectedItems быть списком или IEnumerable какого-то рода?

if(AllSelectedItems == null) 
    { 
     AllSelectedItems = new List<Node>(); 
    } 
    List<Node> selectedItems = SelectedItems;