2015-06-05 2 views
0

У меня есть древовидная структура, в которой есть выбираемые элементы, с подэлементами, которые могут вызывать некоторое действие кода. При щелчке по элементу подпункта действие должно выполняться, но родительский элемент должен оставаться/становиться выбранным элементом.WPF манипулирует выбранным элементом в treeview

Проблема, с которой я сталкиваюсь, заключается в том, что элемент не отменяется должным образом, в результате чего в древовидной структуре выбрано несколько элементов.

Вот XAML для TreeView:

<TreeView Name="Treeview1" Style="{StaticResource vcc_Treeview}" > 
     <TreeView.ItemTemplate > 
      <HierarchicalDataTemplate ItemsSource="{Binding Children}" > 
       <StackPanel Orientation="Horizontal"> 
        <Image Source="{Binding ImgSrc}" Style="{StaticResource vcc_TreeviewItemImage}" /> 
        <TextBlock Text="{Binding Description}" Style="{StaticResource vcc_TreeviewItemTextblock}" Foreground="{Binding TextColorBrush}" /> 
       </StackPanel> 
      </HierarchicalDataTemplate> 
     </TreeView.ItemTemplate> 
     <TreeView.ItemContainerStyle> 
      <Style TargetType="TreeViewItem"> 
       <Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay, Converter={StaticResource clsBindingDebugger}}" /> 
      </Style> 
     </TreeView.ItemContainerStyle> 
    </TreeView> 

clsBindingDebugger не делает ничего, кроме отладки печати преобразованного значения и проходит через конвертируемость и ConvertBack значения.

Далее несколько сокращенный вариант TreeViewItem класса

Public Class MyTreeviewItem 
Implements INotifyPropertyChanged 

Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged 

Public Event MyTreeviewItem_ExpandedChanged(MTI As MyTreeviewItem, IsExpanded As Boolean) 
Public Event MyTreeviewItem_SelectedChanged(MTI As MyTreeviewItem, IsSelected As Boolean) 



Public Sub New(Optional Level_ As Integer = 1, Optional ByVal Key_ As String = "") 
    MyBase.New() 
    Me.Children = New ObservableCollection(Of MyTreeviewItem) 
    _Key = Key_ 
    _Level = Level_ 
End Sub 

Private _Level As Integer 
Public Property Level As Integer 
    Get 
     Level = _Level 
    End Get 
    Set(value As Integer) 
     _Level = value 
    End Set 
End Property 

Private _Descr As String = "" 
Public Property Description As String 
    Get 
     Description = _Descr 
    End Get 
    Set(value As String) 
     _Descr = value 
     RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Description")) 
    End Set 
End Property 

Private _Key As String = "" 
Public Property Key As String 
    Get 
     Key = _Key 
    End Get 
    Set(value As String) 
     _Key = value 
     RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Key")) 
    End Set 
End Property 

Private _ImgSrc As ImageSource 
Public Property ImgSrc As ImageSource 
    Get 
     ImgSrc = _ImgSrc 
    End Get 
    Set(value As ImageSource) 
     _ImgSrc = value 
    End Set 
End Property 

Private _Children As ObservableCollection(Of MyTreeviewItem) 
Public Property Children As ObservableCollection(Of MyTreeviewItem) 
    Get 
     Return _Children 
    End Get 
    Set(value As ObservableCollection(Of MyTreeviewItem)) 
     _Children = value 
    End Set 
End Property 

Private _IsSelected As Boolean 
Overloads Property IsSelected As Boolean 
    Get 
     Return _IsSelected 
    End Get 
    Set(ByVal value As Boolean) 
     _IsSelected = value 
     RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("IsSelected")) 
     RaiseEvent MyTreeviewItem_SelectedChanged(Me, _IsSelected) 
    End Set 
End Property 

Private _IsActionItem As Boolean 
Overloads Property IsActionItem As Boolean 
    Get 
     Return _IsActionItem 
    End Get 
    Set(ByVal value As Boolean) 
     _IsActionItem = value 
    End Set 
End Property 
End Class 

Наконец я вызвать событие MyTreeviewItem_SelectedChanged:

Private ReselectingParent As Boolean = False 

Private Sub MyTreeviewItem_SelectedChanged(MTI As MyTreeviewItem, IsSelected As Boolean) 
Debug.Print(MTI.Description & " Selected = " & IsSelected) 
If ReselectingParent Then Exit Sub 

If IsSelected Then 

    'Do some (action) stuff here 

    If MTI.IsActionItem AndAlso MTI.Parent IsNot Nothing Then 
     ReselectingParent = True 'to prevent this sub from being executed with the next 2 lines 
     MTI.IsSelected = False 
     MTI.Parent.IsSelected = True 
     ReselectingParent = False 
    End If 
End If 
End Sub 

Пусть TreeView выглядит следующим образом:

item 1 
--Action 1 
--Action 2 
Item 2 
--Action 3 
--Action 4 

В моей начальной выбран пункт 2 позиции. Теперь я нажимаю «Действие 1», поэтому действие должно быть выполнено, а затем элемент 1 должен быть выбранным. Результаты Debug.Print в этих линиях:

ConvertBack: False 
Item 2 Selected = False 
Convert: False 
ConvertBack: True 
Action 2 Selected = True 
Action 2 Selected = False 
Convert: True 
Item 1 Selected = True 
Convert: False 

На данный момент Пункт 1 выбран, как это должно быть. Теперь нажмите Действие 3.

ConvertBack: False 
Action 2 Selected = False 
Convert: False 
ConvertBack: True 
Action 3 Selected = True 
Action 3 Selected = False 
Convert: True 
Item 2 Selected = True 
Convert: False 

В результате Пункт 1 и пункт 2 выбраны оба, где должен быть выбран только Пункт 2. Второй блок отладчика говорит «Action 2 Selected = False», это должно быть «Item 1 Selected = False»

Надеюсь, я понятен. Может ли кто-нибудь указать мне на решение моей проблемы? Спасибо!

ответ

0

Ибо кто заинтересован ...

Я Stille не совсем понимаю, почему код не работает должным образом. Но, видимо, элемент с нажатой клавишей не был отменен должным образом. Вместо того, чтобы называть эти строки:

ReselectingParent = True 'to prevent this sub from being executed with the next 2 lines 
    MTI.IsSelected = False 
    MTI.Parent.IsSelected = True 
    ReselectingParent = False 

непосредственно в MyTreeviewItem_SelectedChanged я теперь называю таймер вместо этого. В событии timer_elapsed я вызываю четыре строки. Очевидно, что первичный выбор элемента действия не был завершен при вызове кода, чтобы выбрать его родительский. Это уродливое обходное решение, но оно работает для меня ...

Смежные вопросы