ListView.ItemContainerGenerator.ContainerFromItem(item) return null after 20 items
first of all I want to explain what I'm trying to do. I have a ListView
in a UserControl
with a DataTemplate
defined as a resource. I want to hide a button inside the DataTemplate. Sounds easy, but ....
The code I'm using is
<UserControl.Resources>
<DataTemplate x:Key="Proyectos">
<DockPanel Name="Panel" Margin="0,0,0,0" MinWidth="1200" MaxWidth="1200">
<Border Margin="0" BorderBrush="Bisque" BorderThickness="1" DockPanel.Dock="Left">
<StackPanel Margin="0" Width="1135">
<DockPanel>
<TextBlock Text="{Binding titulo}" Name="titulo" FontWeight="Bold" FontSize="12" />
</DockPanel>
<DockPanel >
<TextBlock FontWeight="Bold" Text="Nº Ref. Fundacion: " DockPanel.Dock="Left" Margin="5,开发者_如何学Python0,5,0" FontSize="11"/>
<TextBlock Name="txb_codproy" Text="{Binding codproy}" FontSize="11"/>
<TextBlock FontWeight="Bold" Text=" Nº Ref. Proyecto: " FontSize="11"/>
<TextBlock Text="{Binding registro}" FontSize="11"/>
<TextBlock FontWeight="Bold" Text=" Estado: " FontSize="11"/>
<TextBlock Text="{Binding estados_proyecto.descripcion}" FontSize="11"/>
</DockPanel>
<DockPanel >
<TextBlock FontWeight="Bold" Text="Organismo " DockPanel.Dock="Left" Margin="5,0,5,0" FontSize="11"/>
<TextBlock Text="{Binding organismo.descripcion}" FontSize="11"/>
</DockPanel>
</StackPanel>
</Border>
<Border Margin="0" Width="Auto" BorderBrush="Transparent" BorderThickness="1" Background="White" HorizontalAlignment="Left">
<Button Margin="0,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left" Name="btn_Eliminar" Click="btn_Eliminar_Click" Width="Auto" Height="25" Background="Transparent" BorderBrush="Transparent">
<Image Name="img_eliminar" Width="48" Source="imagenes/borrar.png" Height="19" />
</Button>
</Border>
</DockPanel>
</DataTemplate>
</UserControl.Resources>
<Grid Width="1300" Height="845.169">
<ListView Margin="20,120.024,15.247,50" MouseDoubleClick="list_proyectos_MouseDoubleClick" Name="list_proyectos" ItemsSource="{Binding}" ItemTemplate="{StaticResource Proyectos}">
</ListView>
<TextBox Margin="32,12,35,0" Name="txt_busqueda" TextChanged="textBox1_TextChanged" Background="AliceBlue" BorderBrush="Gray" Height="23" VerticalAlignment="Top" />
</Grid>
//////////////////////////////////////////////////////////
public Proyectos(IPrincipal identityA)
{
list_proyectos.ItemsSource = ListaProyectos;
list_proyectos.ItemContainerGenerator.StatusChanged += new EventHandler(ItemContainerGenerator_StatusChanged);
}
void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
{
if (list_proyectos.ItemContainerGenerator.Status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
{
list_proyectos.ItemContainerGenerator.StatusChanged -= ItemContainerGenerator_StatusChanged;
Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Input, new VoidDelegate(DelayedAction));
}
}
delegate void VoidDelegate();
void DelayedAction()
{
foreach (object item in list_proyectos.Items)
{
ListBoxItem lbitem = (ListBoxItem)list_proyectos.ItemContainerGenerator.ContainerFromItem(item);
if (lbitem != null)
{
ContentPresenter contentPresenter = FindVisualChild<ContentPresenter>(lbitem);
DataTemplate myDataTemplate = contentPresenter.ContentTemplate;
Button b = (Button)lbitem.ContentTemplate.FindName("btn_Eliminar", contentPresenter);
b.Visibility = Visibility.Hidden;
}
}
}
private T FindVisualChild<T>(DependencyObject obj)
where T : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is T)
return (T)child;
}
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
T childOfChild = FindVisualChild<T>(child);
if (childOfChild != null)
return childOfChild;
}
return null;
}
I found two problems with this,
This line
(ListBoxItem)list_proyectos.ItemContainerGenerator.ContainerFromItem(item);
returns null after the 16th item. The listview has 1576 itemsWhen the ListView is shown and the first 16 items have the button hidden, if I scroll down to the end and then go to top again the buttons are visible again.
The ListView is using virtualization, therefore it will not have created any containers for items that it knows it doesn't have to display. This is a "good thing", especially considering you have 1576 items.
Perhaps you can explain why you want to be able to get the container for the item that is not visible and we can provide better suggestions as far as what you can do.
精彩评论