簡體   English   中英

C#WPF選項卡從ListBox外部導航到ListBoxItem內部

[英]C# WPF Tab Navigate to control inside of a ListBoxItem from outside of ListBox

我有一個帶有版本文本框,按鈕和可擴展和收縮的ListBox的窗口。 每個ListBox項都有多個文本框。 我試圖找到一種方法,標簽從該境外導航ListBox的第一個TextBox中的第一個項目ListBox 我可以將其導航到ListBox本身,如果按下向下箭頭鍵,它將選擇第一個項目,但這很笨拙。 我需要它直接將標簽從ListBox之外的選項卡切換到ListBox內部的選項卡。

以下是一些我用於ListBox的XAML。

                    <ListBox x:Name="add_users_listbox" Margin="2,116,-8,0" BorderThickness="0" Height="322" Padding="0,0,0,0"
                             HorizontalContentAlignment="Center" VerticalContentAlignment="Top" 
                             HorizontalAlignment="Center" VerticalAlignment="Top"
                             SelectionMode="Single"
                             IsTabStop="True"
                             TabIndex="1004"
                             Background="{x:Null}" BorderBrush="{x:Null}"
                             ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                             ScrollViewer.CanContentScroll="False"
                             ItemsSource="{Binding Add_User_Binding}"
                             SelectedIndex="{Binding Add_User_Selected_Index, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">

                        <ListBox.Resources>
                            <Style TargetType="{x:Type ScrollBar}" BasedOn="{StaticResource ScrollBar_Rounded}"/>
                            <Style TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource CustomListBoxItemStyle}"/>
                            <Style TargetType="{x:Type ListBox}" >
                                <Setter Property="KeyboardNavigation.TabNavigation" Value="Continue" />
                            </Style>
                        </ListBox.Resources>

                        <ListBox.ItemTemplate>

                            <DataTemplate>
                                <Grid Height="60" Background="Transparent"
                                      HorizontalAlignment="Center" VerticalAlignment="Top">

                                    <TextBox Height="26" Width="102" Padding="0,-1,0,1" Margin="2,2,0,0"
                                                 HorizontalAlignment="Left" VerticalAlignment="Top" HorizontalContentAlignment="Left" VerticalContentAlignment="Center"
                                                 FontFamily="Segoe UI" FontSize="16" FontWeight="Bold"
                                                 TextWrapping="NoWrap" IsReadOnlyCaretVisible="True" UndoLimit="10" AllowDrop="False" MaxLines="1"
                                                 TabIndex="{Binding First_TabIndex}"
                                                 MaxLength="20"
                                                 TextChanged="first_last_textbox_TextChanged"
                                                 PreviewTextInput="first_last_textbox_PreviewTextInput"
                                                 Text="{Binding First_Textbox, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, ValidatesOnDataErrors=True}">
                                    </TextBox>

                                </Grid>
                            </DataTemplate>
                        </ListBox.ItemTemplate>

                    </ListBox>

只需使您的ListBox IsTabStop="False"和LitBoxItemStyle都可以。 我將此設置器添加到ListBoxItemStyle中: <Setter Property="IsTabStop" Value="False"/>

  <ListBox x:Name="add_users_listbox" Grid.Row="1"  BorderThickness="0" Height="322" Padding="0,0,0,0"
                         HorizontalContentAlignment="Center" VerticalContentAlignment="Top" 
                         HorizontalAlignment="Center" VerticalAlignment="Top"
                         SelectionMode="Single"
                         IsTabStop="False"
                         TabIndex="1004"
                         Background="{x:Null}" BorderBrush="{x:Null}"
                         ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                         ScrollViewer.CanContentScroll="False"
                         ItemsSource="{Binding Add_User_Binding}"
                         SelectedIndex="{Binding Add_User_Selected_Index, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">

        <ListBox.Resources>
            <Style TargetType="{x:Type ScrollBar} BasedOn="{StaticResource ScrollBar_Rounded}" "/> 
            <Style TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource CustomListBoxItemStyle}">                     
                <Setter Property="IsTabStop" Value="False"/>
            </Style>
            <Style TargetType="{x:Type ListBox}" >
                <Setter Property="KeyboardNavigation.TabNavigation" Value="Continue" />
            </Style>
        </ListBox.Resources>

        <ListBox.ItemTemplate>

            <DataTemplate>
                <Grid Height="60" Background="Transparent"
                                  HorizontalAlignment="Center" VerticalAlignment="Top">

                    <TextBox Height="26" Width="102" Padding="0,-1,0,1" Margin="2,2,0,0"
                                             HorizontalAlignment="Left" VerticalAlignment="Top" HorizontalContentAlignment="Left" VerticalContentAlignment="Center"
                                             FontFamily="Segoe UI" FontSize="16" FontWeight="Bold"
                                             TextWrapping="NoWrap" IsReadOnlyCaretVisible="True" UndoLimit="10" AllowDrop="False" MaxLines="1"                                                  
                                             MaxLength="20"
                                             TextChanged="first_last_textbox_TextChanged"
                                             PreviewTextInput="first_last_textbox_PreviewTextInput"
                                             Text="{Binding First_Textbox, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}">
                    </TextBox>

                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>

    </ListBox>

因此,這可能不是實現此目的的理想方法,但它確實有效。 首先,我們在DataTemplateTextBox添加一個綁定標簽

    ItemsSource="{Binding ListBox_Item_Collection}">

    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid>
                <TextBox Text="{Binding First_Textbox, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"
                         Tag="{Binding Index}">
                </TextBox>
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>

為簡單起見,我將該標簽綁定到ItemSource集合中的相應索引。

                int index = Add_User_Binding.Count;

                ListBox_Item_Collection.Add(new SomeDataType()
                {
                    Index = index,
                    The_Textbox = "Stuff in TextBox",
                });

下一步是在此控件之前的用戶控件中添加KeyDown事件。 在這種情況下,我們將找到帶有該標簽的元素,然后使用Dispatcher進行聚焦。

    private void Preview_TextBox_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Tab)
        {
            string tag = "0";
            IEnumerable<TextBox> elements = FindVisualChildren<TextBox>(this).Where(x => x.Tag != null && x.Tag.ToString() == tag);

            foreach (TextBox element in elements)
            {
                FocusElement(element);
            }
        }
    }

    public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
    {
        if (depObj != null)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                if (child != null && child is T)
                {
                    yield return (T)child;
                }

                foreach (T childOfChild in FindVisualChildren<T>(child))
                {
                    yield return childOfChild;
                }
            }
        }
    }

    private void FocusElement(IInputElement element)
    {
        if (element != null)
        {
            Dispatcher.BeginInvoke
            (System.Windows.Threading.DispatcherPriority.ContextIdle,
            new Action(delegate ()
            {
                Keyboard.Focus(element);
            }));
        }
    }

如您所見,很多工作要做的事情應該更簡單。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM