views:

649

answers:

1

hi first of all, I want to explain what I'm treating to do. I have a ListView in a usercontrol with a DataTemplate define like a resource. I want to hide a button inside the DataTemplate. Sounds easy, but ....

the code i'm using is

            <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); return null after the 16 item. the listview have 1576 items

  2. when the ListView is show and the first 16 item have the button hide, if I move the scroll down to the end and then go to top again the button are visible again.

+1  A: 

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.

Drew Marsh
OK put in few words, the behavior I expect is hide the delete button inside the ListView when a user dont have the Administration rol.
germandb
Then you should use a binding within the template which changes the visibility of the button based on whether or not the user is an admin. Assuming you had an IsAdmin property somewhere in your View Model you would just need to bind the Visibility property to that with a BooleanToVisibilityConverter.
Drew Marsh
thanks for the reply, i'm working in it
germandb