none
PropertyGridのIMEモード設定について RRS feed

  • 質問

  • WinXP VS2005 VisualBasicで質問致します。

     プロパティグリッドコントロールを使用して、選択されたアイテムに応じてIMEモードを変えたいと思っています。

     フォームにPropertyGridを1つ貼り付け、SelectedGridItemChangedイベントで選択されたアイテムのラベルが"X","Y","Width","Height"であれば
     IMEモードをOFFに、それ以外ならONにします。下記がコードです。

    1 Private Sub PropertyGrid_SelectedGridItemChanged(ByVal sender As System.ObjectByVal e As System.Windows.Forms.SelectedGridItemChangedEventArgs) Handles PropertyGrid.SelectedGridItemChanged  
    2  
    3     Select Case Me.PropertyGrid.SelectedGridItem.Label  
    4         Case "X""Width""Y""Height" 
    5             Me.PropertyGrid.ImeMode = Windows.Forms.ImeMode.OFF  
    6         Case Else 
    7             Me.PropertyGrid.ImeMode = Windows.Forms.ImeMode.On 
    8     End Select 
    9  
    10 End Sub 
    11  

    このコードで動作させましたが、IMEモードは変化しませんでした。
    また、ブレークポイントをSelect Case ・・・ に仕掛け、ステップで追ってみたのですが
         Me.PropertyGrid.ImeMode = Windows.Forms.ImeMode.OFF
    このコードを通った直後にMe.PropertyGrid.ImeModeをウォッチするとOFFになっています。

    何か足りない部分がありましたら教えて下さい。
    よろしくお願い致します。

    • 編集済み Kakizaki 2009年3月4日 6:59 コードフォーマットを適用したため
    2009年3月3日 8:56

回答

  • 編集用のTextBoxを捕まえてモードを変更してみる。
    プロパティにIMEモードを属性として与えておいて、編集開始時にその属性をセットします。

    1''' <summary>PropertyGridの編集用TextBoxを監視するクラス</summary> 
    2Public Class PropertyGridIme 
    3    Public Sub New(ByVal Grid As PropertyGrid) 
    4        Me.grid = Grid 
    5        Dim txb As TextBox = GetTextBox(Grid) 
    6        If (txb IsNot NothingThen 
    7            AddHandler txb.GotFocus, AddressOf TextBoxGotFocus 
    8        Else 
    9            AddHandler Grid.SelectedObjectsChanged, AddressOf GridSelectedObjectChanged 
    10        End If 
    11    End Sub 
    12    Private grid As PropertyGrid 
    13 
    14    Private Sub GridSelectedObjectChanged(ByVal sender As ObjectByVal e As EventArgs) 
    15        Dim txb As TextBox = GetTextBox(grid) 
    16        If (txb IsNot NothingThen 
    17            RemoveHandler grid.SelectedObjectsChanged, AddressOf GridSelectedObjectChanged 
    18            AddHandler txb.GotFocus, AddressOf TextBoxGotFocus 
    19        End If 
    20    End Sub 
    21 
    22    Private Sub TextBoxGotFocus(ByVal sender As ObjectByVal e As EventArgs) 
    23        Dim griditem As GridItem = grid.SelectedGridItem 
    24        CType(sender, TextBox).ImeMode = GetImeMode(griditem.PropertyDescriptor.Attributes) 
    25    End Sub 
    26 
    27    Private Function GetImeMode(ByVal attributes As System.ComponentModel.AttributeCollection) As ImeMode 
    28        Dim mode As ImeMode = ImeMode.NoControl 
    29        Dim imeatr As PropertyGridIMEAttribute 
    30        For Each atr As Attribute In attributes 
    31            imeatr = TryCast(atr, PropertyGridIMEAttribute) 
    32            If (imeatr IsNot NothingThen 
    33                mode = imeatr.ImeMode 
    34                Exit For 
    35            End If 
    36        Next 
    37        Console.WriteLine(mode.ToString()) 
    38        Return mode 
    39    End Function 
    40 
    41    Private Shared Function GetTextBox(ByVal ctl As Control) As TextBox 
    42        Dim txb As TextBox = TryCast(ctl, TextBox) 
    43        If (txb Is NothingThen 
    44            For Each child As Control In ctl.Controls 
    45                txb = GetTextBox(child) 
    46                If (txb IsNot NothingThen 
    47                    Exit For 
    48                End If 
    49            Next 
    50        End If 
    51        Return txb 
    52    End Function 
    53End Class 
    54 
    55''' <summary>PropertyGridの編集用時に設定したいIMEを指定する属性</summary> 
    56<System.AttributeUsage(AttributeTargets.Property)> _ 
    57Public Class PropertyGridIMEAttribute 
    58    Inherits System.Attribute 
    59    Public Sub New(ByVal imemode As ImeMode) 
    60        _ImeMode = imemode 
    61    End Sub 
    62 
    63    Public ReadOnly Property ImeMode() As ImeMode 
    64        Get 
    65            Return _ImeMode 
    66        End Get 
    67    End Property 
    68    Private _ImeMode As ImeMode 
    69End Class 
    70 
    71 
    72 
    73Public Class Form1 
    74    Inherits System.Windows.Forms.Form 
    75 
    76    Protected Overrides Sub OnLoad(ByVal e As System.EventArgs) 
    77        MyBase.OnLoad(e) 
    78 
    79        Dim grid As New PropertyGrid() 
    80        grid.Dock = DockStyle.Fill 
    81        Me.Controls.Add(grid) 
    82 
    83        grid.Tag = New PropertyGridIme(grid) 
    84        grid.SelectedObject = New TestData() 
    85    End Sub 
    86 
    87    ''' <summary>テスト表示用のデータクラス</summary> 
    88    Public Class TestData 
    89        <PropertyGridIMEAttribute(Windows.Forms.ImeMode.Disable)> _ 
    90        Public Property Disable() As String 
    91            Get 
    92                Return _Disable 
    93            End Get 
    94            Set(ByVal value As String
    95                _Disable = value 
    96            End Set 
    97        End Property 
    98        Private _Disable As String = String.Empty 
    99 
    100        <PropertyGridIMEAttribute(Windows.Forms.ImeMode.NoControl)> _ 
    101        Public Property NoControl() As String 
    102            Get 
    103                Return _NoControl 
    104            End Get 
    105            Set(ByVal value As String
    106                _NoControl = value 
    107            End Set 
    108        End Property 
    109        Private _NoControl As String = String.Empty 
    110 
    111        <PropertyGridIMEAttribute(Windows.Forms.ImeMode.Katakana)> _ 
    112        Public Property Katakana() As String 
    113            Get 
    114                Return _Katakana 
    115            End Get 
    116            Set(ByVal value As String
    117                _Katakana = value 
    118            End Set 
    119        End Property 
    120        Private _Katakana As String = String.Empty 
    121    End Class 
    122End Class 
    • 回答としてマーク Kakizaki 2009年3月4日 6:48
    2009年3月3日 13:51

すべての返信

  • ImeMode はそのコントロールにフォーカスが当たったときの IME の初期入力モードを設定するプロパティであり、現在の入力モードを動的に変更するプロパティではありません。
    WPF なら TSF のラッパとして InputMethod クラスが用意されるようになりましたが、WinForm ではそういうのが存在していないため Win32API を直接呼び出して設定する必要があります。ImmSetConversionStatus 関数を調べてみてください。

    ※TSF : Text Service Framework、漢字変換等を扱う Windows ネイティブのフレームワーク。旧来使用されていた IMM という仕組みに替わるもの。ImmSetConversionStatus などはその IMM で用意されている関数。
    2009年3月3日 9:52
  • 編集用のTextBoxを捕まえてモードを変更してみる。
    プロパティにIMEモードを属性として与えておいて、編集開始時にその属性をセットします。

    1''' <summary>PropertyGridの編集用TextBoxを監視するクラス</summary> 
    2Public Class PropertyGridIme 
    3    Public Sub New(ByVal Grid As PropertyGrid) 
    4        Me.grid = Grid 
    5        Dim txb As TextBox = GetTextBox(Grid) 
    6        If (txb IsNot NothingThen 
    7            AddHandler txb.GotFocus, AddressOf TextBoxGotFocus 
    8        Else 
    9            AddHandler Grid.SelectedObjectsChanged, AddressOf GridSelectedObjectChanged 
    10        End If 
    11    End Sub 
    12    Private grid As PropertyGrid 
    13 
    14    Private Sub GridSelectedObjectChanged(ByVal sender As ObjectByVal e As EventArgs) 
    15        Dim txb As TextBox = GetTextBox(grid) 
    16        If (txb IsNot NothingThen 
    17            RemoveHandler grid.SelectedObjectsChanged, AddressOf GridSelectedObjectChanged 
    18            AddHandler txb.GotFocus, AddressOf TextBoxGotFocus 
    19        End If 
    20    End Sub 
    21 
    22    Private Sub TextBoxGotFocus(ByVal sender As ObjectByVal e As EventArgs) 
    23        Dim griditem As GridItem = grid.SelectedGridItem 
    24        CType(sender, TextBox).ImeMode = GetImeMode(griditem.PropertyDescriptor.Attributes) 
    25    End Sub 
    26 
    27    Private Function GetImeMode(ByVal attributes As System.ComponentModel.AttributeCollection) As ImeMode 
    28        Dim mode As ImeMode = ImeMode.NoControl 
    29        Dim imeatr As PropertyGridIMEAttribute 
    30        For Each atr As Attribute In attributes 
    31            imeatr = TryCast(atr, PropertyGridIMEAttribute) 
    32            If (imeatr IsNot NothingThen 
    33                mode = imeatr.ImeMode 
    34                Exit For 
    35            End If 
    36        Next 
    37        Console.WriteLine(mode.ToString()) 
    38        Return mode 
    39    End Function 
    40 
    41    Private Shared Function GetTextBox(ByVal ctl As Control) As TextBox 
    42        Dim txb As TextBox = TryCast(ctl, TextBox) 
    43        If (txb Is NothingThen 
    44            For Each child As Control In ctl.Controls 
    45                txb = GetTextBox(child) 
    46                If (txb IsNot NothingThen 
    47                    Exit For 
    48                End If 
    49            Next 
    50        End If 
    51        Return txb 
    52    End Function 
    53End Class 
    54 
    55''' <summary>PropertyGridの編集用時に設定したいIMEを指定する属性</summary> 
    56<System.AttributeUsage(AttributeTargets.Property)> _ 
    57Public Class PropertyGridIMEAttribute 
    58    Inherits System.Attribute 
    59    Public Sub New(ByVal imemode As ImeMode) 
    60        _ImeMode = imemode 
    61    End Sub 
    62 
    63    Public ReadOnly Property ImeMode() As ImeMode 
    64        Get 
    65            Return _ImeMode 
    66        End Get 
    67    End Property 
    68    Private _ImeMode As ImeMode 
    69End Class 
    70 
    71 
    72 
    73Public Class Form1 
    74    Inherits System.Windows.Forms.Form 
    75 
    76    Protected Overrides Sub OnLoad(ByVal e As System.EventArgs) 
    77        MyBase.OnLoad(e) 
    78 
    79        Dim grid As New PropertyGrid() 
    80        grid.Dock = DockStyle.Fill 
    81        Me.Controls.Add(grid) 
    82 
    83        grid.Tag = New PropertyGridIme(grid) 
    84        grid.SelectedObject = New TestData() 
    85    End Sub 
    86 
    87    ''' <summary>テスト表示用のデータクラス</summary> 
    88    Public Class TestData 
    89        <PropertyGridIMEAttribute(Windows.Forms.ImeMode.Disable)> _ 
    90        Public Property Disable() As String 
    91            Get 
    92                Return _Disable 
    93            End Get 
    94            Set(ByVal value As String
    95                _Disable = value 
    96            End Set 
    97        End Property 
    98        Private _Disable As String = String.Empty 
    99 
    100        <PropertyGridIMEAttribute(Windows.Forms.ImeMode.NoControl)> _ 
    101        Public Property NoControl() As String 
    102            Get 
    103                Return _NoControl 
    104            End Get 
    105            Set(ByVal value As String
    106                _NoControl = value 
    107            End Set 
    108        End Property 
    109        Private _NoControl As String = String.Empty 
    110 
    111        <PropertyGridIMEAttribute(Windows.Forms.ImeMode.Katakana)> _ 
    112        Public Property Katakana() As String 
    113            Get 
    114                Return _Katakana 
    115            End Get 
    116            Set(ByVal value As String
    117                _Katakana = value 
    118            End Set 
    119        End Property 
    120        Private _Katakana As String = String.Empty 
    121    End Class 
    122End Class 
    • 回答としてマーク Kakizaki 2009年3月4日 6:48
    2009年3月3日 13:51
  •  gekka 様
     御教示頂いたコードを参考に、各プロパティにIMEモードの属性を持たせて制御するようにしたところ
     思い通りの動作に改善しました。ありがとうございました。

    Hongliang 様
     ImeModeプロパティが動的に変更できないというプロパティでは無いということを知りませんでした。
     とても勉強になりました。ありがとうございました。
    2009年3月4日 6:43