回答編集履歴

2 DropDown後の再タッチでDropDownが閉じない不具合を修正

mikupedia

mikupedia score 127

2017/01/30 15:17  投稿

twyujiro15様のアドバイスをもとに再度ビヘイビアを検討してみました。
ComboBoxから親ScrollViewerを検索して、
TouchDownイベントをハンドリングするようにしています。
ハンドリングするタイミングはDropDownOpendイベントとしています。
```VB
   Public Class CloseDropDownBehavior
       Inherits Behavior(Of ComboBox)
       Private _ScrollViewer As ScrollViewer
       Protected Overrides Sub OnAttached()
           MyBase.OnAttached()
           AddHandler AssociatedObject.Loaded, AddressOf AssociatedObject_Loaded
           AddHandler AssociatedObject.TouchDown, AddressOf AssociatedObject_TouchDown  
           AddHandler AssociatedObject.DropDownOpened, AddressOf AssociatedObject_DropDownOpened
           AddHandler AssociatedObject.DropDownClosed, AddressOf AssociatedObject_DropDownClosed
       End Sub
       Protected Overrides Sub OnDetaching()
           MyBase.OnDetaching()
           RemoveHandler AssociatedObject.Loaded, AddressOf AssociatedObject_Loaded
           RemoveHandler AssociatedObject.TouchDown, AddressOf AssociatedObject_TouchDown  
           RemoveHandler AssociatedObject.DropDownOpened, AddressOf AssociatedObject_DropDownOpened
           RemoveHandler AssociatedObject.DropDownClosed, AddressOf AssociatedObject_DropDownClosed
           AssociatedObject_DropDownClosed(_ScrollViewer, New EventArgs)
       End Sub
       Private Sub AssociatedObject_Loaded(sender As Object, e As RoutedEventArgs)
           _ScrollViewer = AssociatedObject.
               Parents(Of ScrollViewer).
               Where(Function(x) x.PanningMode <> PanningMode.None).
               FirstOrDefault
       End Sub  
 
       Private Sub AssociatedObject_TouchDown(sender As Object, e As TouchEventArgs)  
           'ComboBoxタッチ時はScrollViewerのタッチを抑制  
           'これをしないとコンボボックスDropDown後の再タッチでDropDownを閉じることができない  
           e.Handled = True  
       End Sub
       Private Sub AssociatedObject_DropDownOpened(sender As Object, e As EventArgs)
           If _ScrollViewer Is Nothing Then Return
           AddHandler _ScrollViewer.TouchDown, AddressOf ScrollViewer_TouchDown
       End Sub
       Private Sub AssociatedObject_DropDownClosed(sender As Object, e As EventArgs)
           If _ScrollViewer Is Nothing Then Return
           RemoveHandler _ScrollViewer.TouchDown, AddressOf ScrollViewer_TouchDown
       End Sub
       Private Sub ScrollViewer_TouchDown(sender As Object, e As RoutedEventArgs)
           AssociatedObject.IsDropDownOpen = False
       End Sub
   End Class
```
※Parentsメソッドは親エレメントを取得するための拡張メソッドです。
1 誤記修正

mikupedia

mikupedia score 127

2017/01/30 13:04  投稿

twyujiro15様のアドバイスをもとに再度ビヘイビアを検討してみました。
ComboBoxから親ScrollViewerを検索して、
TouchDownイベントをハンドリングするようにしています。
ハンドリングするタイミングはDropDownOpendイベントとしています。
```VB
   Public Class CloseDropDownBehavior
       Inherits Behavior(Of ComboBox)
       Private _ScrollViewer As ScrollViewer
       Protected Overrides Sub OnAttached()
           MyBase.OnAttached()
           AddHandler AssociatedObject.Loaded, AddressOf AssociatedObject_Loaded
           AddHandler AssociatedObject.DropDownOpened, AddressOf AssociatedObject_DropDownOpened
           AddHandler AssociatedObject.DropDownClosed, AddressOf AssociatedObject_DropDownClosed
       End Sub
       Protected Overrides Sub OnDetaching()
           MyBase.OnDetaching()
           RemoveHandler AssociatedObject.Loaded, AddressOf AssociatedObject_Loaded
           RemoveHandler AssociatedObject.DropDownOpened, AddressOf AssociatedObject_DropDownOpened
           RemoveHandler AssociatedObject.DropDownClosed, AddressOf AssociatedObject_DropDownClosed
           AssociatedObject_DropDownClosed(_ScrollViewer, New EventArgs)
       End Sub
       Private Sub AssociatedObject_Loaded(sender As Object, e As RoutedEventArgs)
           _ScrollViewer = AssociatedObject.
               Parents(Of ScrollViewer).
               Where(Function(x) x.PanningMode <> PanningMode.None).
               FirstOrDefault
       End Sub
       Private Sub AssociatedObject_DropDownOpened(sender As Object, e As EventArgs)
           If _ScrollViewer Is Nothing Then Return
           AddHandler _ScrollViewer.TouchDown, AddressOf ScrollViewer_TouchDown
       End Sub
       Private Sub AssociatedObject_DropDownClosed(sender As Object, e As EventArgs)
           If _ScrollViewer Is Nothing Then Return
           RemoveHandler _ScrollViewer.GotFocus, AddressOf ScrollViewer_TouchDown
           RemoveHandler _ScrollViewer.TouchDown, AddressOf ScrollViewer_TouchDown
       End Sub
       Private Sub ScrollViewer_TouchDown(sender As Object, e As RoutedEventArgs)
           AssociatedObject.IsDropDownOpen = False
       End Sub
   End Class
```
※Parentsメソッドは親エレメントを取得するための拡張メソッドです。

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る