Click here to Skip to main content
15,887,214 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have what I am sure is an extremely common requirement, but Googling around has so far failed to leave me any wiser about the neatest way to make the items of a ListBox editable in-place.

Note that I do still require the notion of a currently-selected item for the items in the list.

I have a ListBox defined as follows:

<DataTemplate x:Key="DataTemplateContact">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <TextBlock Grid.Row="0" Grid.Column="0" Text="Name:"/>
        <TextBox Grid.Row="0" Grid.Column="1" Text="{Binding FullName}"/>
        <TextBlock Grid.Row="1" Grid.Column="0" Text="Telephone:"/>
        <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding MainTelephoneNumber}"/>
    </Grid>
</DataTemplate>

<ListBox ItemsSource="{Binding Contacts}" ItemTemplate="{StaticResource DataTemplateContact}"/>


If I click on a 'dead' part of an item, the WPF selection-changed mechanism kicks in and sets the currently-selected item, which is great. The problem is if I click on either of the TextBox controls. I can begin typing in these boxes, but as far as I can tell, WPF doesn't seem to be aware that I am doing anything.

If I set IsEnabled="False" on the TextBox fields then this fixes part of the problem. If I click on a TextBox, WPF recognises that the currently-selected item has changed and this is set accordingly in my View-Model. The problem then becomes how to tell when the currently-being-edited item in the ListBox loses focus.

Can anyone please point me at a neat solution? Can I maybe do something using triggers?

Any help at all would be very much appreciated.

Kind wishes ~ Patrick

What I have tried:

I have half-cobbled something together by handling loads of events in the UI (e.g. ListBox.SelectionChanged, ListBox.MouseDoubleclick, and trying to catch clicks anywhere else in the window), but this all feels very scruffy and puts an uncomfortable amount of logic in my XAML code-behind file.

I have recently tried this:

<Style x:Key="TestStyle" TargetType="TextBox">
    <Setter Property="Focusable" Value="False"/>
    <Style.Triggers>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}}, Path=IsSelected}" Value="True">
            <Setter Property="Background" Value="Crimson"/>
            <Setter Property="Focusable" Value="True"/>
        </DataTrigger>
    </Style.Triggers>
</Style>


The crimson colour is set okay but the TextBox doesn't become editable. Could anyone please explain why?
Posted
Updated 27-Feb-17 23:00pm
v2
Comments
jimmson 27-Feb-17 9:59am    
Hi Patrick. From your description, I'm not sure whether ListBox is really what you looking for. What exact ListBox features do you need?
Patrick Skelton 27-Feb-17 10:07am    
Hi.

I'm afraid my choice was based simply on the fact that I didn't know there was an alternative. The list is not part of a master-detail view or anything like that. The screen displays a single customer on the left and a list of their contacts on the right. Making sure the correct list of contacts is displayed for the customer is already working fine, so the actual list of contacts can be thought of as existing in isolation if that makes sense.
jimmson 27-Feb-17 10:16am    
By my opinion, the ListBox would be very bad choice. There are better alternatives, but it depends on many factors. The first thing - do you need to reuse this control in other parts of your application?
Patrick Skelton 27-Feb-17 10:20am    
There is always the possibility that I might need the same functionality elsewhere, but for now this is a one-off in this application. If I need to reuse it, I'll worry about it later. Hopefully by then I will have a better understanding of all this.
jimmson 27-Feb-17 10:33am    
Ok, I understand. I sent my answer as solution. I need to go for today, but I'll be here tomorrow if you have some questions about my answer.

Hi Patrick,

from our conversation I would suggest to use ItemsControl. This WPF control has ItemsSource property that you can bind to your list of customers/contacts and is easy to style and set ItemTemplate. It requires to learn how to do it but it's not difficult and you will get rid of the problems you have with ListBox.

ItemsControl Class (System.Windows.Controls)[^]
http://www.wpf-tutorial.com/list-controls/itemscontrol/[^]
 
Share this answer
 
Comments
Patrick Skelton 28-Feb-17 4:53am    
Bit confused here. The tutorial above says at the end, "If you want the user to be able to select items from the list, then you're better off with one of the other controls, e.g. the ListBox or the ListView." I do need to keep the notion of having a selected item. Sorry if that wasn't clear. I will amend the original question.

Also, I'm sure an ItemsControl will do what I want, but I'm rather pressed for time (as I'm sure we all are) and was hoping to avoid such a learning curve.

I thought I had a found a simple solution, which I have added to my question, and wonder if you (or anyone) can spot why it isn't working?
jimmson 28-Feb-17 6:16am    
Hi Patrick, I'm sorry, I thought that you don't need to get item selected. I tried to run your code and textboxes are editable. Only problem I see is that it needs two clicks instead of just one, but I can edit them.
Patrick Skelton 28-Feb-17 9:15am    
That's weird. Something else must be breaking it for me, because I can't edit the text boxes. I have a solution based on switching templates, which has got me most of the way there. I will post it when I am sure it works. Thanks again.
Hi Patrick - it sounds like you're describing the scenarios supported by IEditableCollectionView. This allows you to swap backwards and forwards between a display template and an editable template. I describe how to deal with this here[^].
 
Share this answer
 
Comments
Patrick Skelton 28-Feb-17 5:03am    
Wow! Looks good but (I'm hoping) a bit of overkill for now. I will have a play with it when I (a) have a bit more time or (b) have finally torn my last piece of hair out.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900