1

I want to present a listbox with TextBlocks as items. When the user clicks/selects an item it changes into a TextBox for editing. As soon as the controls loses focus the item would turn back to a TextBlock.

The following XAML is almost working in that the TextBlock does turn into a TextBox when it's selected. It also turns back to a TextBlock if I select another item on the list. The problem is that if I move out of the listbox (in this case to the Add New text box) the list item stays as a TextBox.

The question ( WPF ListViewItem lost focus event - How to get at the event? ) looked promising but I can't make it work. I tried using the IsFocused property but then I wasn't able to edit the textbox because when I got into the textbox the listboxitem would go out of focus and thus turning back to a TextBlock before I had a chance to edit the text.

How can I make the TextBox turn back to TextBlock if the listbox/item loses the focus?

(Any other implementation that accomplishes the goal are also welcomed)

<Window x:Class="MyView.MainWindow1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" Title="MainWindow1" Height="300" Width="200"> <Window.Resources> <DataTemplate x:Key="ItemTemplate"> <TextBlock Text="{Binding Name}" /> </DataTemplate> <DataTemplate x:Key="SelectedTemplate"> <TextBox Text="{Binding Name, Mode=TwoWay}" /> </DataTemplate> <Style TargetType="{x:Type ListBoxItem}" x:Key="ContainerStyle"> <Setter Property="ContentTemplate" Value="{StaticResource ItemTemplate}" /> <Style.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter Property="ContentTemplate" Value="{StaticResource SelectedTemplate}" /> </Trigger> </Style.Triggers> </Style> </Window.Resources> <StackPanel > <ListBox ItemsSource="{Binding Departments}" HorizontalContentAlignment="Stretch" ItemContainerStyle="{StaticResource ContainerStyle}" /> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <TextBox Text="{Binding NewDepartmentName, Mode=TwoWay}" /> <Button Grid.Column="1" Width="50" Content="Add" Command="{Binding Path=AddNewDepartmentCommand}" /> </Grid> </StackPanel> </Window> 
4
  • Use an attached property on the ListBox to hack your way into it. Do a foreach on the items (and items changing). Latch onto each item's Focus event/property and when it changes, use VisualTreeHelper or LogicalTreeHelper to see if any children (i.e. TextBox) have focus.. Commented Feb 24, 2012 at 22:08
  • I tried doing this but failed miserably. Could you please post an example of how to do it? Commented Feb 29, 2012 at 17:39
  • I just took another shot at modifying the textbox's look (Phil's answer) and I now have something I can work with. Thanks. Commented Feb 29, 2012 at 23:30
  • can you edit phil's answer to the final result Commented Mar 1, 2012 at 14:56

2 Answers 2

2

This doesn't answer your question, but gives an alternative solution by making a textbox look like a textblock when the listboxitem isn't selected:

<Page.Resources> <ResourceDictionary> <Style x:Key="ListBoxSelectableTextBox" TargetType="{x:Type TextBox}"> <Setter Property="IsHitTestVisible" Value="False" /> <Style.Triggers> <DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}, AncestorLevel=1}}" Value="True"> <Setter Property="IsHitTestVisible" Value="True" /> </DataTrigger> </Style.Triggers> </Style> </ResourceDictionary> </Page.Resources> <Grid> <ListBox ItemsSource="{Binding Departments}" HorizontalContentAlignment="Stretch"> <ListBox.ItemTemplate> <DataTemplate> <TextBox Margin="5" Style="{StaticResource ListBoxSelectableTextBox}" Text="{Binding Name}" BorderBrush="{x:Null}"/> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Grid> 
Sign up to request clarification or add additional context in comments.

Comments

0

There are many ways you can do this:

  1. Above answer
  2. Create a TextBox style based on TextBoxBase such that when disabled, it makes the TextBox look like a TextBlock by setting the BorderThickness="0", Background="transparent"
  3. Have both TextBlock and TextBox on each ListViewItem and using the above answer technique hide and show the TextBlock/TextBox accrodingly

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.