C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

ツリー一括表示

PropertyGridのTAB移動について /や (19/05/16(Thu) 09:29) #90983
Re[1]: PropertyGridのTAB移動について /魔界の仮面弁士 (19/05/16(Thu) 11:37) #90989
  └ Re[2]: PropertyGridのTAB移動について /魔界の仮面弁士 (19/05/16(Thu) 11:43) #90990
    └ Re[3]: PropertyGridのTAB移動について /や (19/05/17(Fri) 10:31) #91008
      └ Re[4]: PropertyGridのTAB移動について /魔界の仮面弁士 (19/05/17(Fri) 11:39) #91010
        └ Re[5]: PropertyGridのTAB移動について /魔界の仮面弁士 (19/05/17(Fri) 11:59) #91012
          └ Re[6]: PropertyGridのTAB移動について /や (19/05/17(Fri) 12:58) #91013 解決済み


親記事 / ▼[ 90989 ]
■90983 / 親階層)  PropertyGridのTAB移動について
□投稿者/ や (1回)-(2019/05/16(Thu) 09:29:02)

分類:[VB.NET/VB2005 以降] 

開発環境:Windows10
開発言語:Visual Studio2013/VB.net

PropertyGrid で実行時に、項目をTAB移動させたいのですが、具体的にどうやれば実現できるかわかりません。
矢印キーでの移動は何もせず動いているのですが。

[ □ Tree ] 返信 編集キー/

▲[ 90983 ] / ▼[ 90990 ]
■90989 / 1階層)  Re[1]: PropertyGridのTAB移動について
□投稿者/ 魔界の仮面弁士 (2168回)-(2019/05/16(Thu) 11:37:24)
No90983 (や さん) に返信
> PropertyGrid で実行時に、項目をTAB移動させたいのですが、具体的にどうやれば実現できるかわかりません。

Public Class YourPropertyGrid
  Inherits System.Windows.Forms.PropertyGrid

  Protected Overrides Function ProcessKeyPreview(ByRef m As Message) As Boolean
    Const WM_KEYDOWN As Integer = &H100
    If m.Msg = WM_KEYDOWN AndAlso m.WParam = New IntPtr(Keys.Tab) Then
      Return SelectNextGridItem()
    End If
    Return MyBase.ProcessKeyPreview(m)
  End Function

  Private Function SelectNextGridItem() As Boolean
    Dim selected = SelectedGridItem
    Dim root = GetRootGridItem(selected)
    Dim gridItems = Descendents(root).ToList()
    Dim currentIndex = gridItems.IndexOf(selected)
    Dim nextIndex = Math.Min(gridItems.Count - 1, currentIndex + 1)
    Return gridItems(nextIndex).Select()
  End Function

  Private Function GetRootGridItem(item As GridItem) As GridItem
    Return If(item.GridItemType = GridItemType.Root, item, GetRootGridItem(item.Parent))
  End Function
  Private Iterator Function Descendents(item As GridItem) As IEnumerable(Of GridItem)
    If item.GridItemType = GridItemType.ArrayValue Then
      Return
    ElseIf item.GridItemType = GridItemType.Property Then
      Yield item
    Else
      For Each x As GridItem In item.GridItems
        For Each y As GridItem In Descendents(x)
          Yield y
        Next
      Next
    End If
  End Function
End Class
[ 親 90983 / □ Tree ] 返信 編集キー/

▲[ 90989 ] / ▼[ 91008 ]
■90990 / 2階層)  Re[2]: PropertyGridのTAB移動について
□投稿者/ 魔界の仮面弁士 (2169回)-(2019/05/16(Thu) 11:43:34)
No90989 (魔界の仮面弁士) に追記
>   Private Function SelectNextGridItem() As Boolean
>     Dim selected = SelectedGridItem
>     Dim root = GetRootGridItem(selected)
>     Dim gridItems = Descendents(root).ToList()
>     Dim currentIndex = gridItems.IndexOf(selected)
>     Dim nextIndex = Math.Min(gridItems.Count - 1, currentIndex + 1)
>     Return gridItems(nextIndex).Select()
>   End Function

一番最後の行で Tab を押したときに先頭に戻したい場合は、上記の
 Dim nextIndex = Math.Min(gridItems.Count - 1, currentIndex + 1)
の部分を
 Dim nextIndex = If(currentIndex < gridItems.Count - 1, currentIndex + 1, 0)
にします。
[ 親 90983 / □ Tree ] 返信 編集キー/

▲[ 90990 ] / ▼[ 91010 ]
■91008 / 3階層)  Re[3]: PropertyGridのTAB移動について
□投稿者/ や (2回)-(2019/05/17(Fri) 10:31:48)
コードも書いて頂き、ありがとうございます。
アイテム順にTAB移動できましたが、サブアイテムがある場合はどのようになるのでしょうか。
よろしくお願い致します。
[ 親 90983 / □ Tree ] 返信 編集キー/

▲[ 91008 ] / ▼[ 91012 ]
■91010 / 4階層)  Re[4]: PropertyGridのTAB移動について
□投稿者/ 魔界の仮面弁士 (2171回)-(2019/05/17(Fri) 11:39:03)
No91008 (や さん) に返信
> アイテム順にTAB移動できましたが、サブアイテムがある場合はどのようになるのでしょうか。

それでは、これでは如何でしょう。

Private Iterator Function Descendents(item As GridItem) As IEnumerable(Of GridItem)
  If item.GridItemType = GridItemType.ArrayValue Then
    Return
  ElseIf item.GridItemType = GridItemType.Property Then
    Yield item
  End If
  For Each x As GridItem In item.GridItems
    If x.Parent.Expanded Then
      For Each y As GridItem In Descendents(x)
        Yield y
      Next
    End If
  Next
End Function


私の方法では、カテゴリー選択時(.GridItemType = GridItemType.Category)には
タブキーで「次のアイテム」ではなく「次のコントロール」に移動してしまうという
問題もあるようです。(ProcessKeyPreview に WM_KEYDOWN が送られてこない)
[ 親 90983 / □ Tree ] 返信 編集キー/

▲[ 91010 ] / ▼[ 91013 ]
■91012 / 5階層)  Re[5]: PropertyGridのTAB移動について
□投稿者/ 魔界の仮面弁士 (2173回)-(2019/05/17(Fri) 11:59:36)
No91010 (魔界の仮面弁士) に追記
> 私の方法では、カテゴリー選択時(.GridItemType = GridItemType.Category)には
> タブキーで「次のアイテム」ではなく「次のコントロール」に移動してしまうという
> 問題もあるようです。(ProcessKeyPreview に WM_KEYDOWN が送られてこない)


ProcessKeyPreview で WM_KEYDOWN を拾う方法を使うのではなく、
ProcessTabKey を使うことで、カテゴリー選択時にも反応できるようです。

ということで、追加改修バージョン。


Public Class YourPropertyGrid
  Inherits System.Windows.Forms.PropertyGrid

  Protected Overrides Function ProcessTabKey(forward As Boolean) As Boolean
    'ProcessKeyPreview で WM_KEYDOWN を拾う方法を廃止し、
    'ProcessTabKey を用いるようにしました。
    Return SelectNextGridItem(forward)
  End Function

  Private Function SelectNextGridItem(forward As Boolean) As Boolean
    Dim selected = SelectedGridItem
    If selected Is Nothing Then
      '選択しているアイテムが無い場合にエラーになる問題を修正しました。
      Return False
    End If
    Dim root = GetRootGridItem(selected)
    Dim gridItems = Descendents(root).ToList()
    Dim currentIndex = gridItems.IndexOf(selected)
    Dim nextIndex As Integer
    'Shift + Tab での逆順送りに対応させました。
    If forward Then
      nextIndex = If(currentIndex < gridItems.Count - 1, currentIndex + 1, 0)
    Else
      nextIndex = If(currentIndex < 1, 0, currentIndex - 1)
    End If
    Return gridItems(nextIndex).Select()
  End Function

  Private Function GetRootGridItem(item As GridItem) As GridItem
    Return If(item.GridItemType = GridItemType.Root, item, GetRootGridItem(item.Parent))
  End Function

  Private Iterator Function Descendents(item As GridItem) As IEnumerable(Of GridItem)
    If item.GridItemType = GridItemType.ArrayValue Then
      Return
    ElseIf item.GridItemType = GridItemType.Property Or item.GridItemType = GridItemType.Category Then
      'カテゴリーからのタブ移動が可能になったので、
      'GridItemType.Category も列挙対象に加えるようにしました。
      Yield item
    End If
    For Each x As GridItem In item.GridItems
      '折りたたまれているアイテムは列挙しないようにしました。
      If x.Parent.Expanded Then
        For Each y As GridItem In Descendents(x)
          Yield y
        Next
      End If
    Next
  End Function
End Class
[ 親 90983 / □ Tree ] 返信 編集キー/

▲[ 91012 ] / 返信無し
■91013 / 6階層)  Re[6]: PropertyGridのTAB移動について
□投稿者/ や (3回)-(2019/05/17(Fri) 12:58:19)
色々とご教授頂き、ありがとうございました。
思っていた動きが実現できました!
解決済み
[ 親 90983 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -