none
listbox内のTextboxにカーソルを持っていく RRS feed

  • 質問

  • 環境はVisualStudio.net VB 2010です。

    表題の処理ができずに困っております。

    Listboxには画像とTextboxが対になる形で配置してあり、入力する画像を増やすと

    左記ペアが1個ずつ増えていくものです。

    この時ListBox内のある項目を選択時にキーボードの上下を押すとそのイベントをもって

    押されたキーが上下ならばListboxの選択されている項目が上下に移動するコードを実装し、

    動くところまではできたのですが、そのListBox内にあるテキストボックスにカーソルを

    もっていく方法がわかりません。

    諸先輩方、単純な質問かとは思いますがご教授なにとぞよろしくお願いします。

    ソースコード部を下記します。

                   
                        lstFName.SelectedIndex = 0 ’選択項目の指定
                        lstFName.Items(selnum).→この後にどのようにTextbox指定すればよいかが

    わかりません。TextboxのWPFコード部の宣言は下記となります。

      <TextBox x:Name="TxtFilename" Text="{Binding Path=ttt,UpdateSourceTrigger=PropertyChanged}"
                                          Grid.Row="3" Width="auto"></TextBox>

    2017年7月7日 8:17

回答

  • おそらく以下の感じでできると思いますが、サンプルコードがC#です。VBに変換できますか?

    Set Focus of TextBox in ListView
    https://social.msdn.microsoft.com/Forums/vstudio/en-US/1e9a98c3-b4be-40af-99bd-828491ddcd69/set-focus-of-textbox-in-listview?forum=wpf


    ★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/

    2017年7月7日 8:51
    モデレータ
  • こんな?

    <Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
        <DockPanel>
            <StackPanel Orientation="Horizontal" DockPanel.Dock="Top" Margin="5">
                <CheckBox Content="並び順を変更する" x:Name="chkSwap"/>
            </StackPanel>
            <ListBox ItemsSource="{Binding Path=Items}" x:Name="lstFName">
                <ListBox.ItemContainerStyle>
                    <Style TargetType="{x:Type ListBoxItem}">
                        <EventSetter Event="PreviewKeyDown" Handler="ListBoxItem_PreviewKeyDown" />
                        <EventSetter Event="GotKeyboardFocus" Handler="ListBoxItem_GotKeyboardFocus" />
                        <Style.Triggers>
                            <Trigger Property="IsKeyboardFocusWithin" Value="true">
                                <Setter Property="IsSelected" Value="True" />
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </ListBox.ItemContainerStyle>
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="auto"/>
                                <RowDefinition Height="auto"/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>
                            <Border BorderBrush="Black" BorderThickness="1" Background="LightGray">
                                <Image Width="50" Height="50" x:Name="thisIsDummy"/>
                            </Border>
                            <TextBox x:Name="TxtFilename" Text="{Binding Path=ttt,UpdateSourceTrigger=PropertyChanged}" Grid.Row="3" Width="auto"/>
                        </Grid>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </DockPanel>
    </Window>
    Class MainWindow 
    
        Sub New()
            ' この呼び出しはデザイナーで必要です。
            InitializeComponent()
    
            ' InitializeComponent() 呼び出しの後で初期化を追加します。
            Me.DataContext = Model.CreateTestModel()
        End Sub
    
        Private Sub ListBoxItem_PreviewKeyDown(sender As System.Object, e As System.Windows.Input.KeyEventArgs)
            Dim container As ListBoxItem = CType(sender, ListBoxItem)
            Dim index = Me.lstFName.ItemContainerGenerator.IndexFromContainer(container)
    
            If (Me.chkSwap.IsChecked) Then
                '並び順を入れ替える場合
                Dim item As Object = Me.lstFName.ItemContainerGenerator.ItemFromContainer(container)
                Dim list As System.Collections.IList = Me.lstFName.ItemsSource
    
                If (e.Key = Key.Up AndAlso 0 < index) Then
                    list.RemoveAt(index)
                    index = index - 1
                    list.Insert(index, item)
                ElseIf (e.Key = Key.Down AndAlso index < Me.lstFName.Items.Count - 1) Then
                    list.RemoveAt(index)
                    index = index + 1
                    list.Insert(index, item)
                Else
                    Exit Sub
                End If
    
                '選択対象を変更してそこまでスクロール
                Me.lstFName.SelectedIndex = index
                Me.lstFName.ScrollIntoView(Me.lstFName.SelectedItem)
    
                '選択した項目にフォーカスを
                container = Me.lstFName.ItemContainerGenerator.ContainerFromIndex(Me.lstFName.SelectedIndex)
                If (container IsNot Nothing) Then
                    container.Focus()
                End If
                e.Handled = True
            Else
                '単純にListBoxの選択状態を上下させるだけ
                Dim request As TraversalRequest
                If (e.Key = Key.Up) Then
                    request = New TraversalRequest(FocusNavigationDirection.Up)
                ElseIf (e.Key = Key.Down) Then
                    request = New TraversalRequest(FocusNavigationDirection.Down)
                Else
                    Exit Sub
                End If
                Dim ui As UIElement = TryCast(Keyboard.FocusedElement, UIElement)
                If (ui IsNot Nothing) Then
                    ui.MoveFocus(request)
                    e.Handled = True
                End If
            End If
        End Sub
    
        Private Sub ListBoxItem_GotKeyboardFocus(sender As System.Object, e As System.Windows.Input.KeyboardFocusChangedEventArgs)
            'ListBoxItemにフォーカスが
            Dim container As ListBoxItem = CType(sender, ListBoxItem)
            If (Keyboard.FocusedElement Is container) Then
                'キーボードフォーカスがListBoxItemにあるならTextBoxをさがして
                Dim cp As ContentPresenter = FindChild(Of ContentPresenter)(container)
                If (cp IsNot Nothing) Then
                    Dim txb As TextBox = TryCast(cp.ContentTemplate.FindName("TxtFilename", cp), TextBox)
                    If (txb IsNot Nothing AndAlso Not txb.IsKeyboardFocused) Then
                        'フォーカスをセット
                        txb.Focus()
                        txb.SelectAll()
                        e.Handled = True
                    End If
                End If
            End If
        End Sub
    
    
        ''' <summary>子要素を探す</summary>
        Private Function FindChild(Of T As DependencyObject)(ByVal d As DependencyObject) As DependencyObject
            Dim count As Integer = VisualTreeHelper.GetChildrenCount(d)
            For i As Integer = 0 To count - 1
                Dim ret As T
                Dim child As DependencyObject
                child = VisualTreeHelper.GetChild(d, i)
                ret = TryCast(child, T)
                If (ret Is Nothing) Then
                    ret = FindChild(Of T)(child)
                End If
    
                If (ret IsNot Nothing) Then
                    Return ret
                End If
            Next
            Return Nothing
        End Function
    
    End Class
    
    
    Class Model
        Public Property Items As New System.Collections.ObjectModel.ObservableCollection(Of Item)
    
        Public Shared Function CreateTestModel() As Model
            Dim m As New Model
            For i As Integer = 1 To 100
                m.Items.Add(New Item() With {.ttt = i.ToString()})
            Next
            Return m
        End Function
    End Class
    
    Class Item
        Implements System.ComponentModel.INotifyPropertyChanged
    
        Public Property ttt As String
            Get
                Return _ttt
            End Get
            Set(value As String)
                _ttt = value
                OnPropertyChagned("ttt")
            End Set
        End Property
        Private _ttt As String
    
        Public Event PropertyChanged(sender As Object, e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
        Protected Sub OnPropertyChagned(ByVal name As String)
            RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs(name))
        End Sub
    End Class

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2017年7月7日 11:07

すべての返信

  • おそらく以下の感じでできると思いますが、サンプルコードがC#です。VBに変換できますか?

    Set Focus of TextBox in ListView
    https://social.msdn.microsoft.com/Forums/vstudio/en-US/1e9a98c3-b4be-40af-99bd-828491ddcd69/set-focus-of-textbox-in-listview?forum=wpf


    ★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/

    2017年7月7日 8:51
    モデレータ
  • こんな?

    <Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
        <DockPanel>
            <StackPanel Orientation="Horizontal" DockPanel.Dock="Top" Margin="5">
                <CheckBox Content="並び順を変更する" x:Name="chkSwap"/>
            </StackPanel>
            <ListBox ItemsSource="{Binding Path=Items}" x:Name="lstFName">
                <ListBox.ItemContainerStyle>
                    <Style TargetType="{x:Type ListBoxItem}">
                        <EventSetter Event="PreviewKeyDown" Handler="ListBoxItem_PreviewKeyDown" />
                        <EventSetter Event="GotKeyboardFocus" Handler="ListBoxItem_GotKeyboardFocus" />
                        <Style.Triggers>
                            <Trigger Property="IsKeyboardFocusWithin" Value="true">
                                <Setter Property="IsSelected" Value="True" />
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </ListBox.ItemContainerStyle>
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="auto"/>
                                <RowDefinition Height="auto"/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>
                            <Border BorderBrush="Black" BorderThickness="1" Background="LightGray">
                                <Image Width="50" Height="50" x:Name="thisIsDummy"/>
                            </Border>
                            <TextBox x:Name="TxtFilename" Text="{Binding Path=ttt,UpdateSourceTrigger=PropertyChanged}" Grid.Row="3" Width="auto"/>
                        </Grid>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </DockPanel>
    </Window>
    Class MainWindow 
    
        Sub New()
            ' この呼び出しはデザイナーで必要です。
            InitializeComponent()
    
            ' InitializeComponent() 呼び出しの後で初期化を追加します。
            Me.DataContext = Model.CreateTestModel()
        End Sub
    
        Private Sub ListBoxItem_PreviewKeyDown(sender As System.Object, e As System.Windows.Input.KeyEventArgs)
            Dim container As ListBoxItem = CType(sender, ListBoxItem)
            Dim index = Me.lstFName.ItemContainerGenerator.IndexFromContainer(container)
    
            If (Me.chkSwap.IsChecked) Then
                '並び順を入れ替える場合
                Dim item As Object = Me.lstFName.ItemContainerGenerator.ItemFromContainer(container)
                Dim list As System.Collections.IList = Me.lstFName.ItemsSource
    
                If (e.Key = Key.Up AndAlso 0 < index) Then
                    list.RemoveAt(index)
                    index = index - 1
                    list.Insert(index, item)
                ElseIf (e.Key = Key.Down AndAlso index < Me.lstFName.Items.Count - 1) Then
                    list.RemoveAt(index)
                    index = index + 1
                    list.Insert(index, item)
                Else
                    Exit Sub
                End If
    
                '選択対象を変更してそこまでスクロール
                Me.lstFName.SelectedIndex = index
                Me.lstFName.ScrollIntoView(Me.lstFName.SelectedItem)
    
                '選択した項目にフォーカスを
                container = Me.lstFName.ItemContainerGenerator.ContainerFromIndex(Me.lstFName.SelectedIndex)
                If (container IsNot Nothing) Then
                    container.Focus()
                End If
                e.Handled = True
            Else
                '単純にListBoxの選択状態を上下させるだけ
                Dim request As TraversalRequest
                If (e.Key = Key.Up) Then
                    request = New TraversalRequest(FocusNavigationDirection.Up)
                ElseIf (e.Key = Key.Down) Then
                    request = New TraversalRequest(FocusNavigationDirection.Down)
                Else
                    Exit Sub
                End If
                Dim ui As UIElement = TryCast(Keyboard.FocusedElement, UIElement)
                If (ui IsNot Nothing) Then
                    ui.MoveFocus(request)
                    e.Handled = True
                End If
            End If
        End Sub
    
        Private Sub ListBoxItem_GotKeyboardFocus(sender As System.Object, e As System.Windows.Input.KeyboardFocusChangedEventArgs)
            'ListBoxItemにフォーカスが
            Dim container As ListBoxItem = CType(sender, ListBoxItem)
            If (Keyboard.FocusedElement Is container) Then
                'キーボードフォーカスがListBoxItemにあるならTextBoxをさがして
                Dim cp As ContentPresenter = FindChild(Of ContentPresenter)(container)
                If (cp IsNot Nothing) Then
                    Dim txb As TextBox = TryCast(cp.ContentTemplate.FindName("TxtFilename", cp), TextBox)
                    If (txb IsNot Nothing AndAlso Not txb.IsKeyboardFocused) Then
                        'フォーカスをセット
                        txb.Focus()
                        txb.SelectAll()
                        e.Handled = True
                    End If
                End If
            End If
        End Sub
    
    
        ''' <summary>子要素を探す</summary>
        Private Function FindChild(Of T As DependencyObject)(ByVal d As DependencyObject) As DependencyObject
            Dim count As Integer = VisualTreeHelper.GetChildrenCount(d)
            For i As Integer = 0 To count - 1
                Dim ret As T
                Dim child As DependencyObject
                child = VisualTreeHelper.GetChild(d, i)
                ret = TryCast(child, T)
                If (ret Is Nothing) Then
                    ret = FindChild(Of T)(child)
                End If
    
                If (ret IsNot Nothing) Then
                    Return ret
                End If
            Next
            Return Nothing
        End Function
    
    End Class
    
    
    Class Model
        Public Property Items As New System.Collections.ObjectModel.ObservableCollection(Of Item)
    
        Public Shared Function CreateTestModel() As Model
            Dim m As New Model
            For i As Integer = 1 To 100
                m.Items.Add(New Item() With {.ttt = i.ToString()})
            Next
            Return m
        End Function
    End Class
    
    Class Item
        Implements System.ComponentModel.INotifyPropertyChanged
    
        Public Property ttt As String
            Get
                Return _ttt
            End Get
            Set(value As String)
                _ttt = value
                OnPropertyChagned("ttt")
            End Set
        End Property
        Private _ttt As String
    
        Public Event PropertyChanged(sender As Object, e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
        Protected Sub OnPropertyChagned(ByVal name As String)
            RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs(name))
        End Sub
    End Class

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2017年7月7日 11:07
  • pen800 さん、こんにちは
    フォーラム オペレーターの立花楓です。
     
    本件についてその後いかがでしょうか。
    trapemiya さん、gekka さんにお寄せいただいた情報がご参考になると思いましたので、こちらで回答マークを付けさせていただきました。

    なにか進展がございましたらこちらのスレッドへご返信いただけますと幸いです。

    よろしくお願いします。


    MSDN/TechNet Community Support 立花楓


    2017年7月18日 6:23
    モデレータ