トップ回答者
TreeViewイベントについて

質問
-
OS:Windows10
開発環境
VisualStudio2015
.net Framework 4.5
言語
WPF(VB)
ツリービューにHierarchicalDataTemplateを利用して項目を表示させています。
この項目をダブルクリックにてイベントを発生させたいのですがイベントが発生しません。
<TreeView.ItemContainerStyle> <Style TargetType="{x:Type TreeViewItem}"> <!--<EventSetter Event="MouseDoubleClick" Handler="menuTreeView_MouseDoubleClick"/>--> <Setter Property="IsExpanded" Value="{Binding Path=IsExpanded, Mode=TwoWay}" /> <Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" /> <Setter Property="FontWeight" Value="Normal" /> <Style.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter Property="FontWeight" Value="Bold" /> </Trigger> </Style.Triggers> </Style> </TreeView.ItemContainerStyle> <TreeView.ItemTemplate> <HierarchicalDataTemplate DataType="local:MenuWindow.MenuNodeItem" ItemsSource="{Binding Children}" > <TextBlock Text="{Binding Name}" /> <HierarchicalDataTemplate.ItemContainerStyle> <Style TargetType="{x:Type TreeViewItem}"> <EventSetter Event="MouseDoubleClick" Handler="menuTreeView_MouseDoubleClick"/> </Style> </HierarchicalDataTemplate.ItemContainerStyle> </HierarchicalDataTemplate> </TreeView.ItemTemplate>
そこで、TreeView.ItemContainerStyleにEventSetterを記述したところ、
イベントは発生するのですが、項目の階層分イベントが発生します。
※3階層目の項目ダブルクリックにて、イベントが3回発生する。
こちらについて、解決方法をご存知の方はおられませんか?
以上、よろしくお願い致します。
回答
-
TreeViewItemは大まかにいうと「ヘッダ部分」「下の階層一覧」というの2個の要素で構成されています。
つまり、TreeViewItemにMouseDoubleClickを設定すると、子の要素のダブルクリックは親の階層のダブルクリックにもなってしまいます。
そのため、1回のダブルクリックが階層の数だけ発生してしまいます。1回だけにするにはTreeViewでDoubleClickイベントを設定するか、HierarchicalDataTemplate内の要素にDoubleClickイベントを設定します。
#TreeViewItemのテンプレートの書き換えだと大変なので、<TreeView ItemsSource="{Binding}" MouseDoubleClick="TreeView_MouseDoubleClick"> <TreeView.ItemContainerStyle> <Style TargetType="{x:Type TreeViewItem}"> <Setter Property="IsExpanded" Value="{Binding Path=IsExpanded, Mode=TwoWay}" /> <Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" /> <Setter Property="FontWeight" Value="Normal" /> <Style.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter Property="FontWeight" Value="Bold" /> </Trigger> </Style.Triggers> </Style> </TreeView.ItemContainerStyle> <TreeView.ItemTemplate> <HierarchicalDataTemplate DataType="local:MenuWindow.MenuNodeItem" ItemsSource="{Binding Children}" > <ContentControl MouseDoubleClick="TreeViewItemHeader_MouseDoubleClick"> <TextBlock Text="{Binding Name}"/> </ContentControl> <!--<HierarchicalDataTemplate.ItemContainerStyle> このItemContainerStyleはこの階層の下の階層のTreeViewItemのスタイルです ですからこの階層でダブルクリックしてもイベントは何もおきません <Style TargetType="{x:Type TreeViewItem}"> <EventSetter Event="MouseDoubleClick" Handler="menuTreeView_MouseDoubleClick" /> </Style> </HierarchicalDataTemplate.ItemContainerStyle>--> </HierarchicalDataTemplate> </TreeView.ItemTemplate> </TreeView>
''' <summary>TreeViewにDoubleClickイベントを設定する場合</summary> Private Sub TreeView_MouseDoubleClick(sender As Object, e As MouseButtonEventArgs) Dim d As DependencyObject = e.OriginalSource Do While (d IsNot sender) If (TypeOf d Is TreeViewItem) Then Dim tvi As TreeViewItem = CType(d, TreeViewItem) Dim item = TryCast(tvi.DataContext, MenuWindow.MenuNodeItem) If (item IsNot Nothing) Then MessageBox.Show(item.Name) End If Exit Do End If d = VisualTreeHelper.GetParent(d) Loop End Sub
''' <summary>TreeViewItemのContent内にDoubleClickを設定する場合</summary> Private Sub TreeViewItemHeader_MouseDoubleClick(sender As Object, e As MouseButtonEventArgs) Dim fe = CType(e.OriginalSource, FrameworkElement) Dim item = TryCast(fe.DataContext, MenuWindow.MenuNodeItem) If (item IsNot Nothing) Then MessageBox.Show(item.Name) End If End Sub
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年6月21日 0:34
- 回答としてマーク onionsword 2017年6月23日 0:23
すべての返信
-
TreeViewItemは大まかにいうと「ヘッダ部分」「下の階層一覧」というの2個の要素で構成されています。
つまり、TreeViewItemにMouseDoubleClickを設定すると、子の要素のダブルクリックは親の階層のダブルクリックにもなってしまいます。
そのため、1回のダブルクリックが階層の数だけ発生してしまいます。1回だけにするにはTreeViewでDoubleClickイベントを設定するか、HierarchicalDataTemplate内の要素にDoubleClickイベントを設定します。
#TreeViewItemのテンプレートの書き換えだと大変なので、<TreeView ItemsSource="{Binding}" MouseDoubleClick="TreeView_MouseDoubleClick"> <TreeView.ItemContainerStyle> <Style TargetType="{x:Type TreeViewItem}"> <Setter Property="IsExpanded" Value="{Binding Path=IsExpanded, Mode=TwoWay}" /> <Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" /> <Setter Property="FontWeight" Value="Normal" /> <Style.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter Property="FontWeight" Value="Bold" /> </Trigger> </Style.Triggers> </Style> </TreeView.ItemContainerStyle> <TreeView.ItemTemplate> <HierarchicalDataTemplate DataType="local:MenuWindow.MenuNodeItem" ItemsSource="{Binding Children}" > <ContentControl MouseDoubleClick="TreeViewItemHeader_MouseDoubleClick"> <TextBlock Text="{Binding Name}"/> </ContentControl> <!--<HierarchicalDataTemplate.ItemContainerStyle> このItemContainerStyleはこの階層の下の階層のTreeViewItemのスタイルです ですからこの階層でダブルクリックしてもイベントは何もおきません <Style TargetType="{x:Type TreeViewItem}"> <EventSetter Event="MouseDoubleClick" Handler="menuTreeView_MouseDoubleClick" /> </Style> </HierarchicalDataTemplate.ItemContainerStyle>--> </HierarchicalDataTemplate> </TreeView.ItemTemplate> </TreeView>
''' <summary>TreeViewにDoubleClickイベントを設定する場合</summary> Private Sub TreeView_MouseDoubleClick(sender As Object, e As MouseButtonEventArgs) Dim d As DependencyObject = e.OriginalSource Do While (d IsNot sender) If (TypeOf d Is TreeViewItem) Then Dim tvi As TreeViewItem = CType(d, TreeViewItem) Dim item = TryCast(tvi.DataContext, MenuWindow.MenuNodeItem) If (item IsNot Nothing) Then MessageBox.Show(item.Name) End If Exit Do End If d = VisualTreeHelper.GetParent(d) Loop End Sub
''' <summary>TreeViewItemのContent内にDoubleClickを設定する場合</summary> Private Sub TreeViewItemHeader_MouseDoubleClick(sender As Object, e As MouseButtonEventArgs) Dim fe = CType(e.OriginalSource, FrameworkElement) Dim item = TryCast(fe.DataContext, MenuWindow.MenuNodeItem) If (item IsNot Nothing) Then MessageBox.Show(item.Name) End If End Sub
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年6月21日 0:34
- 回答としてマーク onionsword 2017年6月23日 0:23