Accessing a list view item in code behind
I've got a listview that i want to set the tag property to some value (true in this case) so i can have a data trigger change its template. The template works, but clicking on the button and setting the tag does not. Here's how i'm trying to set said tag:
Code Snippet
ListViewItem lvi = _lstVisit.ItemContainerGenerator.ContainerFromItem((sender as Button).Tag as IMyItem) as ListViewItem;
lvi.Tag = true;
This retrieves what seems like the right list view item, but it doesn't set the template properly. Clicking on the button again shows that lvi.Tag is still null.
this is what i had to do, though i was trying to avoid that inter-layer link (we use what is becoming a very lax M/P architecture). Didn't want the model to have knowledge of what the presenter was doing, but i guess it's unavoidable.
Of course, I don't know what you're doing -- but if you have a DataTemplate for each Item bound by an ItemsSource for the ListView, using the tag property to indicate state could be a bit unusual (and certainly doesn't lend itself to an obvious object model).
Are you saying that the lvi.Tag property is immediately null right after you set it?
no, only on the second time around. What i'm having to do for this is rather unusual as it is. You see, in order to handle both a template change for selection and a template change on a button click i'm setting the item template to a control template rather than the ItemContainerStyle to a data template.
Code Snippet
<Trigger Property="ListViewItem.IsSelected" Value="True">
<Setter Property="ListViewItem.Template" Value="{StaticResource gridListRow}"/>
<Setter Property="ListViewItem.Background" Value="LightSteelBlue"/>
</Trigger>
<Trigger Property="ListViewItem.IsSelected" Value="False">
<Setter Property="ListViewItem.Template" Value="{StaticResource gridListRow}"/>
<Setter Property="ListViewItem.Background" Value="White"/>
</Trigger>
<DataTrigger Binding="{Binding IsEditing}" Value="True">
<Setter Property="ListViewItem.Template" Value="{StaticResource entryListRow}"/>
</DataTrigger>
I suppose that i could go back and find some way to handle the style outside of the trigger but i don't think that it overrides the default selection in that case.
The template switching is working now. Unfortunately, the change (the entry row used to be static at the top but i'm trying to have it open in-place) screwed up all the code-behind modification of UIElements. I'm having a bit of trouble with that,
Code Snippet
ListViewItem lvi = _lstVisit.ItemContainerGenerator.ContainerFromItem(m_newVisit) as ListViewItem;
//ContentPresenter localPresenter = FindVisualChild<ContentPresenter>(lvi);
ControlTemplate localTemplate = (ControlTemplate) this.Resources["entryListRow"];
TextBox tDateBox = (TextBox)localTemplate.FindName("_txtDate", lvi);
Would work excepting that the lvi, at this point, hasn't switched over to the new template.
edit: it helps if the trigger isn't commented out. I think i've got this figured out.
Code Snippet
ListViewItem lvi = _lstVisit.ItemContainerGenerator.ContainerFromItem(m_newThingy) as ListViewItem;
ControlTemplate localTemplate = lvi.Template;
TextBox visitDateBox = (TextBox)localTemplate.FindName("_txtDate", lvi);
This code, if i walk through the members seems to be working properly. I can go in and view the children of the template and see "_txtDate" as a registered child. Unfortunately, localTemplate.FindName is returning null no matter what i do. Any ideas?