首先,我想解释一下我要做的事情。我在ListView
中有一个UserControl
,其中DataTemplate
被定义为资源。我想在DataTemplate中隐藏一个按钮。听起来很简单,但是......
我正在使用的代码是
<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,0,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;
}
我发现了两个问题,
此行(ListBoxItem)list_proyectos.ItemContainerGenerator.ContainerFromItem(item);
在第16个项目后返回null。列表视图有1576项
当显示ListView并且前16个项目隐藏了按钮时,如果我向下滚动到最后,然后再次返回顶部,按钮再次可见。
答案 0 :(得分:2)
ListView正在使用虚拟化,因此它不会为它知道不必显示的项目创建任何容器。这是一件“好事”,特别是考虑到你有1576件物品。
也许您可以解释为什么您希望能够获取不可见项目的容器,我们可以提供更好的建议。