0

I have created a listbox with editable textboxes. The code looks like this:

<ListBox Name="subjects_list" Margin="74,154,1039,171" ItemsSource="{Binding ElementName=styles_list, Path=SelectedItem.subjects, Mode=TwoWay}" HorizontalContentAlignment="Stretch" BorderThickness="0" >
   <ListBox.ItemTemplate>
      <DataTemplate>
          <TextBox Name="TextBoxList" Text="{Binding name}" BorderThickness="1" Background="#FFD3E1FF" BorderBrush="#FFA0B8FF" >
             <TextBox.Style>
                <Style TargetType="TextBox">
                   <Style.Triggers>
                      <Trigger Property="IsFocused" Value="True">
                         <Setter Property="Foreground" Value="Green"/>
                         <Setter Property="IsReadOnly" Value="False" />
                      </Trigger>
                      <Trigger Property="IsFocused" Value="False">
                         <Setter Property="Foreground" Value="Black"/>
                         <Setter Property="IsReadOnly" Value="True" />
                      </Trigger>
                   </Style.Triggers>
                </Style>
             </TextBox.Style>
          </TextBox>
       </DataTemplate>
   </ListBox.ItemTemplate>
</ListBox>

I want to change the behaviour of this setup as it turned out to be not exactly what I need. The problem is that on a mouse click, the textbox becomes editable but it is not the selected item in the listbox. I need to have a way to select the item and another way to edit it. My idea is that on a single click I set the textbox as selected item and on a double click the textbox becomes editable. Any suggestions how to achieve this?

  • Have you tried the search function here on Stack Overflow yet? There are plenty of treasures to be found... Possible solutions differ depending on whether you prefer a single click to select the item as well as focusing the textbox or whether you prefer two clicks. For example, see these two answers: https://stackoverflow.com/a/863167/2819245, or https://stackoverflow.com/a/2192380/2819245 –  Jun 11 '17 at 20:10

1 Answers1

0

ItemTemplates are not very friendly for this kind of thing because they are a DataTemplate so the controls in the template (such as your TextBox) only know about the data that its bound to and nothing about the fact that its even in a ListBoxItem in a ListBox.

However, there's a couple of ways you can do this. Generally for the most control, use the ListBox GetContainerForItemOverride() method to use a custom ListBoxItem.

1. If you want to select the list box item automatically whenever the TextBox gets focus: You will need "communication" from the TextBox to the ListBox. RoutedEvents (bubbling) are perfect for this because the TextBox is contained in its ListBox item. So the TextBox GotFocus routed event can be seen by the ListBoxItem that contains it. You could override the ListBox GetContainerForItemOverride() method on the ListBox and return a custom ListBoxItem (e.g. MyListBoxItem derived from ListBoxItem) that handles the GotFocus RoutedEvent. The custom ListBoxItem will set its IsSelected = true; in the event handler. For selection appearance use custom ListBoxItem ControlTemplate as in #2 below.

2. If you want to select using one click and focus in TextBox using another click: For this, you won't necessarily need to derive a custom LisBoxItem nor need to use GetContainerForItemOverride(). You can create a ListBoxItem Controltemplate and use a Grid/Border or other element(s) around the ContentPresenter with a padding/margin such that there is some area around the ContentPresenter (the ContentPresenter is where your ItemTemplate visual, including your TextBox, is placed automatically when the ListBox is populated). See MSDN ListBoxItem ControlTemplate. In the ListBoxItem ControlTemplate you can also customize the border/background color based on IsSelected trigger/binding. If you don't want a large border area around the TextBox you can create a separate area in the ListBoxItem Controltemplate template just for selection indication purposes. For example you could just have a circle/rectangle to the left of the TextBox that has a fill color based on modifying its Fill using IsSelected property Trigger/Binding.