Change TextBock to TextBox in ListView template when it's selected

I'm trying to build an editable ListView. Basically, when nothing is selected it behaves like a regular ListView. When a ListViewItem is selected, I want to change the TextBlocks to TextBox's (or some other kind of control that allows editing.

Here's a simple example of what I'm doing:

<Page x:Class="asdfsad"
xmlns="http://schemas.microsoft.com/winfx/avalon/2005"
xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005"
Title="Transactions" Loaded="blah">
<
Page.Resources>
<
XmlDataProvider x:Key="MyData" XPath="/Transactions">
<
Transactions xmlns="">
<
Transaction Description="asd" Amount="10" Date="1/1/2001" Test="Test" />
<
Transaction Description="asdfs" Amount="20" Date="1/1/2001" Test="Test" />
<
Transaction Description="fdsa" Amount="30" Date="1/1/2001" Test="Test" />
<
Transaction Description="asdfsad" Amount="40" Date="1/1/2001" Test="Test" />
<
Transaction Description="fasdf" Amount="50" Date="1/1/2001" Test="Test" />
</
Transactions>
</
XmlDataProvider>
<
DataTemplate x:Key="description">
<
TextBlock Text="{Binding XPath=@Description}" />
</DataTemplate.Triggers>
</
DataTemplate>
</
Page.Resources>
<
ListView ItemsSource="{Binding Source={StaticResource MyData}, XPath=Transaction}">
<
ListView.View>
<
GridView>
<
GridView.Columns>
<
GridViewColumn Header="Test" CellTemplate="{StaticResource description}" />
<
GridViewColumn Header="Date" DisplayMemberPath="@Date" />
<
GridViewColumn Header="Amount" DisplayMemberPath ="@Amount" />
<
GridViewColumn Header="Description" DisplayMemberPath="@Description" />
</
GridView.Columns>
</
GridView>
</
ListView.View>
</
ListView>
</
Page>

I tried setting up triggers in the DataTemplate but I'm not sure how to change the template. Does anyone have any ideas



Answer this question

Change TextBock to TextBox in ListView template when it's selected

  • Bernie Hizon

    I think the single TextBox with different styling would be the best way. I changed the DataTemplate to this:

    <DataTemplate x:Key="description">
         <
    TextBox Text="{Binding XPath=@Description}">
              <
    TextBox.Style>
                   <
    Style>
                        <
    Style.Triggers>
                             <
    DataTrigger Binding="{Binding Path=IsSelected, RelativeSource=/TemplatedParent}" Value="True">
                                  <
    Setter Property="TextBox.Background" Value="Blue" />
                             </
    DataTrigger>
                        </
    Style.Triggers>
                   </
    Style>
              </
    TextBox.Style>
         </
    TextBox>
    </
    DataTemplate>

    When I select a ListViewItem the TextBox's background doesn't turn blue. I've tried adding another /TemplatedParent to the RelativeSource property but to no avail.


  • LMS65

    First TextBox doesn't have an IsSelected property. You must use IsKeyboardFocused. It will be like this (note that I have used a Trigger instead of DataTrigger, it is much easier):

    <DataTemplate x:Key="description">
    <TextBox Text="{Binding XPath=@Description}">
    <TextBox.Style>
    <Style TargetType="{x:Type TextBox}">
    <Style.Triggers>
    <Trigger Property="IsKeyboardFocused" Value="True">
    <Setter Property="TextBox.Background" Value="Blue" />
    </Trigger>
    </Style.Triggers>
    </Style>
    </TextBox.Style>
    </TextBox>
    </DataTemplate>



  • JensenLee

    My first thought is to use a TextBox at all times, and just enable/disable the editing in the control on selection. This would be much easier to accomplish. If you are worried about visual appearance you can always style the TextBox differently for the two states, which is much easier than replacing elements dynamically using XAML. Using code there is no issue either way.

  • SL-USA

    I do this all the time, its a really neat effect. What I do is I template ListItem, which does have a selected property. Then, use a trigger to is swap out a completely new item template. This also lets you do neet "selected row is bigger than the other rows" effects that are real cool. (Think windows remove programs control panel for an example.) The other nicety is that the selected and unselected templates can be completely unrelated and it works well.

    In the intrest of time I'll just paste some xaml from my current project. You can make the translation.

    <Style x:Key="ActiveComplaintItemStyle"

    TargetType="ListBoxItem">

    <Style.Triggers>

    <Trigger Property="ListBoxItem.IsSelected"

    Value="True">

    <Setter Property="Template"

    Value="{StaticResource ActiveComplaintSelected}"/>

    </Trigger>

    </Style.Triggers>

    </Style>

    ...

    <ListBox Grid.Row="1"

    ItemContainerStyle="{StaticResource ActiveComplaintItemStyle}"

    ItemTemplate="{StaticResource ActiveComplaintUnselected}"

    ItemsSource="{Binding ActiveComplaints}"/>

    the unlisted templates are just normal templates.


  • Change TextBock to TextBox in ListView template when it's selected