I am trying to get a listview to display a list of items made up of textblocks... when the listview item is clicked i would like to show instead a list made up of textboxes...
Below is what i have come up with, it does not work. I have two grids within the templates and was hoping to simply show and hide the grids depending on if the listview item is selected. Where have i gone wrong?
I ripped these visual states from the listview's template itself but i must admit im not sure how they work, or how they are meant to be triggered. Should there be some code behind to do this?
<ListView Grid.Row="2" ItemsSource="{Binding Lines}" HorizontalAlignment="Stretch">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid Name="Readonly">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding One}" Grid.Column="0"/>
<TextBlock Text="{Binding Two}" Grid.Column="1"/>
</Grid>
<Grid Name="Editing" Visibility="Collapsed">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<TextBox Text="{Binding One}" Grid.Column="0"/>
<TextBox Text="{Binding Two}" Grid.Column="1"/>
</Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Selected">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Editing" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Readonly" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Many thanks, Kohan
You are setting the Storyboard Animation up outside the Items that are being rendered. The targets you are specifying are not only out of the scope of the outer page, but they potentially do not exist yet. As a result, the Storyboard cannot be setup when the page is rendered.
Here's what you want to do.
Create a user control that will represent the layout you want in your
ListView
item. When you define yourListView
, be sure to include yourUserControl
in yourDataTemplate
, like this:Now, for the
VisualStates
. You need to set the states up inside theUserControl
. That means a state for Edit and a state for View. A state needs to be localized like this. Think of theButton
control. The states in a button are defined in eachButton
not some shared location.When you are ready to change the state of one of the items, you need to wire it to your code behind. In your code behind, you need to loop through the items in your
ListView
and call a method you create, something likeMakeStateEdit()
andMakeStateView()
. It will be your implementation of those methods that sets the states of the user control. The outside code just trusts it to happen.This means you need to call
VisualStateManager.GoToState(this, "Edit", true);
(or whatever state you create) inside yourUserControl
, in the code-behind. Conversely you might set the "View" state when theMakeStateView()
is called.To iterate a
ListView
Items
property, you need to use a technique like this (http://blog.jerrynixon.com/2012/09/how-to-access-named-control-inside-xaml.html). You'll find that once you start down this path, it really isn't very complicated. You might be disappointed that you can't do all of this in XAML. You can't. But it can be done!Best of luck!
I don't know if visual state changes propagate, so maybe your solution should somehow work, but I would edit the visual states in the ListViewItem template instead (through ItemContainerStyle).