我有一个树状视图,其中有可选择的项,以及可能触发某些代码操作的子项。单击子项时,应执行操作,但父项必须保留/成为选定项。
我面临的问题是项目没有被正确取消选择,导致在树视图中选择多个项目。
以下是treeview的xaml:
<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除了调试打印转换的值并传递转换和转换回值之外什么也不做。
接下来是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
假设树视图看起来像:
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”
我希望我说清楚了。谁能告诉我问题的解决方法?谢谢!
对谁感兴趣。。。
我仍然不太明白为什么代码不能正常工作。但显然,单击的操作项没有被正确取消选择。不要打这些电话:
ReselectingParent = True 'to prevent this sub from being executed with the next 2 lines
MTI.IsSelected = False
MTI.Parent.IsSelected = True
ReselectingParent = False
直接在MyTreeviewItem\u Selected Changed中,我现在改为调用计时器。在timer_appeased事件中,我调用四行。显然,在调用代码选择其父项时,操作项的主选择尚未完成。这是一个丑陋的解决办法,但对我来说很有效。。。
我正在实现一个类别映射器。有2树视图。两者都包含来自不同来源的类别。(即使他们看起来像来自同一个来源) 用户应该能够将一个类别从左侧映射到右侧树状视图的多个。它存储在配置文件中。 但是,当视图最初加载并且用户单击左侧的类别时,我想预选右侧的映射类别,从配置文件加载。 我看到我可以用一个选项来做这件事,但是我没有看到一个选项可以用多个选项来做这件事。 我怎样才能做到这一点? 这里有一个ootb正在运
我有一个绑定到MVVM可观察集合的TreeView。我的项目模板由图像和文本块组成,如以下代码所示: 当然,发生这种情况是因为堆栈面板现在位于选择区域上方。 有什么解决办法吗?
新加入WPF的我正尝试使用TreeView,它提供的灵活性给我留下了难以置信的印象。 到目前为止,我的每个treeview项目都实现了一个扩展器,这是显示每个项目更详细信息并让标题仅显示摘要的好方法。但是,这不适合叶项目,并且浪费了屏幕空间——我的treeview中的每个叶项目(其中有许多)显示的数据量相对较小。 我想要为叶项目实现的是水平包装,而不是垂直列表。设想显示一个网格或(stackpan
我工作在一个WPF应用程序,我有2树视图。两者都有一个ViewModel对象集合作为其ItemsSource。我试图使它,当用户选择一个TreeView中的项目时,其他的选择被更改为空。 但是,我注意到TreeView中的实际项目属于SomethingViewModel类型,而不是TreeView项目。这意味着他们没有选择的财产。我已经尝试将IsSelected属性添加到ViewModel对象,并
我有一个WPF TreeView,希望在所有没有子项的TreeView项目上侦听双击。我的树视图如下所示: 树状视图的内容是这样生成的: 在我的XAML文件中,我定义了一个EventSetter,单击TreeViewItem时应该触发它: 在我的代码隐藏中,我定义了处理程序: 当我双击任何TreeViewItem时,处理程序被触发,但每次发送者都是TreeViewItem“级别1”。我想得到点击的
我正在学习WPF,我想我缺少一些用户控件。我将尝试用例子来演示。基本上,假设我有一个treeview,我想将标签文本绑定到treeview selectedItem。这似乎很简单: 现在,为了使事情复杂化,我将在混合中添加一个用户控件。用户控件基本上是网格中的TreeView: 其目的是用usercontrol替换上面使用的vanilla treeview,并根据所选内容更改标签内容。所以,我试着