Selecting a Textbox Item in a Listbox does not change the selected item of the listbox

后端 未结 15 1331
清酒与你
清酒与你 2020-11-27 04:10

I Have a wpf Listbox that display\'s a list of textboxes. When I click on the Textbox the Listbox selection does not change. I have to click next to the TextBox to select th

相关标签:
15条回答
  • 2020-11-27 04:45

    I'm not entirely sure you would want to set the selection directly as described in the previous answer because I think it would break multiselection and some other scenerios

    . You might want to try restyling a button like below and see what happens.

    <Button ClickMode="Pressed" Focusable="False">
    <Button.Template>
        <ControlTemplate>  // change the template to get rid of all the default chrome 
            <Border Background="Transparent"> // Button won't be clickable without some kind of background set
                <ContentPresenter />
            </Border>
        </ControlTemplate>
    </Button.Template>
    <TextBox />
    

    0 讨论(0)
  • 2020-11-27 04:46

    The Listbox handles item selection but does not know about focus of the textbox embedded within. If you want to change the selection whenever a textbox gets input focus then you need to change the listbox selection manually, afaik.

    0 讨论(0)
  • 2020-11-27 04:48

    Your not very specific about your initial situation. But i assume that you use DataBinding and an ItemTemplate. Thats imho an easy way to do this, as well if your beginner on this topic. This should work:

    <ListBox ItemsSource="{Binding someDataCollection}" Name="myListBox">
       <ListBox.ItemTemplate>
          <DataTemplate>
             <TextBox Text="{Binding datafield}" Tag="{Binding .}"
                      GotFocus="TextBox_GotFocus"/>
          </DataTemplate>
       </ListBox.ItemTemplate>
    </ListBox>
    

    private void TextBox_GotFocus(object sender, RoutedEventArgs e)
    {
       myListBox.SelectedItem = (sender as TextBox).Tag; /* Maybe you need to cast to the type of the objects contained in the collection(bound as ItemSource above) */
    }
    
    0 讨论(0)
  • 2020-11-27 04:53

    We use the following style to set a PreviewGotKeyboardFocus which handles all events of TextBox control and ComboBoxes and such:

        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <EventSetter Event="PreviewGotKeyboardFocus" Handler="SelectCurrentItem"/>
            </Style>
        </ListView.ItemContainerStyle>
    

    And then we select the row in code behind:

        protected void SelectCurrentItem(object sender, KeyboardFocusChangedEventArgs e)
        {
            ListViewItem item = (ListViewItem) sender;
            item.IsSelected = true;
        }
    
    0 讨论(0)
  • 2020-11-27 04:56

    I don't have enough reps to comment, so I am posting my comment as answer. Grazer's solution above does not work in cases where you have another control such as a Button that needs the SelectedItem. This is because as per the Style Trigger, the IsKeyboardFocusWithin becomes false when you click on that Button, and the SelectedItem becomes null.

    0 讨论(0)
  • 2020-11-27 04:57

    Attached behavior based on Arcturus Answer to make it reuseable and to have it not hidden in the code behind.

    Create file with the attached behavior (= attached property)

    public static class SelectListBoxItemWhenControlInsideTheItemIsClickedBehavior
    {
        public static readonly DependencyProperty EnableProperty = DependencyProperty.RegisterAttached(
            "Enable",
            typeof(bool),
            typeof(SelectListBoxItemWhenControlInsideTheItemIsClickedBehavior),
            new FrameworkPropertyMetadata(false, OnEnableChanged));
    
    
        public static bool GetEnable(FrameworkElement frameworkElement)
        {
            return (bool)frameworkElement.GetValue(EnableProperty);
        }
    
    
        public static void SetEnable(FrameworkElement frameworkElement, bool value)
        {
            frameworkElement.SetValue(EnableProperty, value);
        }
    
    
        private static void OnEnableChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if ( d is ListBoxItem listBoxItem)
                listBoxItem.PreviewGotKeyboardFocus += ListBoxItem_PreviewGotKeyboardFocus;
        }
    
        private static void ListBoxItem_PreviewGotKeyboardFocus(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e)
        {
            var listBoxItem = (ListBoxItem)sender;
            listBoxItem.IsSelected = true;
        }
    }
    

    Add it to the resources of your liking.

    For example <Windows.Resources>

    <Window.Resources>
        <Style TargetType="ListViewItem">
            <Setter Property="myBehavior:SelectListBoxItemWhenControlInsideTheItemIsClickedBehavior.Enable" Value="true"/>
        </Style>
    </Window.Resources>
    

    Add namespace

    if visual studio is not clever enough to add it automatically. for example when your project is called "MyApp" and you saved the file in the Folder "MyBehaviors", the Namespace would be under Window:

    <Window
        xmlns:myBehavior="clr-namespace:MyApp.MyBehaviors"
        >
    
    0 讨论(0)
提交回复
热议问题