经过20项ListView.ItemContainerGenerator.ContainerFromItem(项目)返回NULL [英] ListView.ItemContainerGenerator.ContainerFromItem(item) return null after 20 items

查看:352
本文介绍了经过20项ListView.ItemContainerGenerator.ContainerFromItem(项目)返回NULL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先我想解释什么,我试图做的。我有一个的ListView 用户控件与定义的的DataTemplate 作为资源。我想隐藏的DataTemplate内的按钮。听起来很简单,但是......

在code,我用的就是

 < UserControl.Resources>
    <的DataTemplate X:键=PROYECTOS>
        < D​​ockPanel中NAME =面板保证金=0,0,0,0了minWidth =1200了maxWidth =1200>
            < BORDER保证金=0BorderBrush =浓汤了borderThickness =1DockPanel.Dock =左>            < StackPanel的保证金=0WIDTH =1135>
                <&DockPanel中GT;
                    < TextBlock的文本={结合TITULO}NAME =TITULO粗细=大胆字号=12/>
                < / DockPanel中>
                <&DockPanel中GT;
                    < TextBlock的粗细=大胆文本=Nº参考基金会:DockPanel.Dock =左保证金=5,0,5,0字号=11/>
                    < TextBlock的名称=txb_codproy文本={结合codproy}字号=11/>
                    < TextBlock的粗细=大胆文本=Nº参考PROYECTO:字号=11/>
                    < TextBlock的文本={结合registro}字号=11/>
                    < TextBlock的粗细=大胆文本=埃斯塔字号=11/>
                    < TextBlock的文本={结合estados_proyecto.descripcion}字号=11/>
                < / DockPanel中>                <&DockPanel中GT;
                    < TextBlock的粗细=大胆文本=OrganismoDockPanel.Dock =左保证金=5,0,5,0字号=11/>
                    < TextBlock的文本={结合organismo.descripcion}字号=11/>
                < / DockPanel中>            < / StackPanel的>            < /边框>
            < BORDER保证金=0WIDTH =自动BorderBrush =透明了borderThickness =1背景=白的Horizo​​ntalAlignment =左>
                <按钮保证金=0,0,0,0VerticalAlignment =中心的Horizo​​ntalAlignment =左NAME =btn_Eliminar点击=btn_Eliminar_ClickWIDTH =自动HEIGHT =25背景=透明BorderBrush =透明>
                    <图像名称=img_eliminarWIDTH =48来源=imagenes / borrar.pngHEIGHT =19/>
                < /按钮>
            < /边框>
        < / DockPanel中>
    < / DataTemplate中>
< /UserControl.Resources><电网WIDTH =1300HEIGHT =845.169>
    < ListView的保证金=20,120.024,15.247,50MouseDoubleClick =list_proyectos_MouseDoubleClickNAME =list_proyectos的ItemsSource ={}绑定的ItemTemplate ={StaticResource的PROYECTOS}>
    < /&的ListView GT;
    <文本框保证金=32,12,35,0NAME =txt_busqueda框TextChanged =textBox1_TextChanged背景=艾莉斯蓝BorderBrush =灰色HEIGHT =23VerticalAlignment =顶部/>
< /网格和GT;
////////////////////////////////////////////////// ////////公共PROYECTOS(的IPrincipal identityA)
{
     list_proyectos.ItemsSource = ListaProyectos;
     list_proyectos.ItemContainerGenerator.StatusChanged + =新的EventHandler(ItemContainerGenerator_StatusChanged);
}无效ItemContainerGenerator_StatusChanged(对象发件人,EventArgs的发送)
{
    如果(list_proyectos.ItemContainerGenerator.Status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
    {
        list_proyectos.ItemContainerGenerator.StatusChanged - = ItemContainerGenerator_StatusChanged;
        Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Input,新VoidDelegate(DelayedAction));
    }
}委托无效VoidDelegate();无效DelayedAction()
{
    的foreach(在list_proyectos.Items对象项)
    {        ListBoxItem中lbitem =(ListBoxItem中)list_proyectos.ItemContainerGenerator.ContainerFromItem(项目);
        如果(lbitem!= NULL)
        {
            内容presenter内容presenter = FindVisualChild<内容presenter>(lbitem);
            DataTemplate中myDataTemplate =内容presenter.ContentTemplate;
            按钮B =(按钮)lbitem.ContentTemplate.FindName(btn_Eliminar,内容presenter);
            b.Visibility = Visibility.Hidden;
        }    }
}私人ŧFindVisualChild< T>(DependencyObject的OBJ)
    其中T:DependencyObject的
{
    的for(int i = 0; I< VisualTreeHelper.GetChildrenCount(OBJ);我++)
    {
        DependencyObject的孩子= VisualTreeHelper.GetChild(OBJ,I);
        如果(孩子= NULL&放大器;!&安培;孩子是T)
            回报(T)的孩子;
    }    的for(int i = 0; I< VisualTreeHelper.GetChildrenCount(OBJ);我++)
    {
        DependencyObject的孩子= VisualTreeHelper.GetChild(OBJ,I);
        ŧchildOfChild = FindVisualChild< T>(小孩);
        如果(childOfChild!= NULL)
            返回childOfChild;
    }    返回null;
}

我发现了两个问题,


  1. 这行(ListBoxItem中)list_proyectos.ItemContainerGenerator.ContainerFromItem(项目); 16项之后返回null。 ListView中有1576项


  2. 在ListView中显示,并在第一16个项目已按钮隐藏的,如果我向下滚动到最后,然后再去顶部的按钮是可见的一次。



解决方案

ListView控件是使用虚拟化技术,因此它不会创造任何容器,它知道它没有显示的项目。这是一个好东西,特别是考虑到你有1576项。

也许你能解释一下为什么你希望能够得到容器不可见的项目,我们可以尽量提供更好的建议,你可以做什么。

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,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;
}

I found two problems with this,

  1. This line (ListBoxItem)list_proyectos.ItemContainerGenerator.ContainerFromItem(item); returns null after the 16th item. The listview has 1576 items

  2. When 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.

这篇关于经过20项ListView.ItemContainerGenerator.ContainerFromItem(项目)返回NULL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆