0
votes

I am trying to add different button controls inside the listbox dynamically for each listbox item along with the data while populating it. To achieve this, under the datatemplate tag, I have added new stack panel in which I placed button controls. Now, I am trying to find the particular stackpanel in which the buttons are being placed and then make it visible true or false depending on my condition. So, I have tried to find the desired stack panel to get the control over it through looping the listbox items. However, I am getting "Null Reference Exception" while iterating the listbox items. The following is my xaml code and the later is my xaml.cs code:

               <ListBox x:Name="TripList" Height="465" HorizontalAlignment="Left" VerticalAlignment="Top" Width="456" Background="White" Foreground="Blue">
                    <ListBox.ItemTemplate>
                        <DataTemplate>

                            <Border BorderBrush="Black" BorderThickness="0,0,0,4">
                                <StackPanel Orientation="Vertical" Width="456">
                                    <StackPanel Orientation="Vertical">
                                        <StackPanel VerticalAlignment="Top" Orientation="Horizontal">
                                            <TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Left" TextWrapping="Wrap"  VerticalAlignment="Top" Width="370" FontSize="24" Text="{Binding PUDetails}"/>
                                            <TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Right" TextWrapping="Wrap"  VerticalAlignment="Top" FontSize="24" Text="{Binding TripStatus}"/>
                                        </StackPanel>
                                        <StackPanel VerticalAlignment="Top" Orientation="Horizontal">
                                            <StackPanel VerticalAlignment="Top" Orientation="Horizontal" Width="300">
                                                <TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Left" TextWrapping="Wrap"  VerticalAlignment="Top" FontSize="18" Text="Conf: "/>
                                                <TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Left" TextWrapping="Wrap"  VerticalAlignment="Top" FontSize="18" Text="{Binding ConfNumber}"/>
                                            </StackPanel>
                                            <StackPanel VerticalAlignment="Top" Orientation="Horizontal">
                                                <TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Right" TextWrapping="Wrap"  VerticalAlignment="Top" FontSize="18" Text="Est Do Tm: "/>
                                                <TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Right" TextWrapping="Wrap"  VerticalAlignment="Top" FontSize="18" Text="{Binding DOTime}"/>
                                            </StackPanel>
                                        </StackPanel>
                                        <StackPanel VerticalAlignment="Top" Orientation="Vertical">
                                            <StackPanel x:Name="stacktest" Background="Azure" Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top">
                                                <TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Left" TextWrapping="Wrap"  VerticalAlignment="Top" FontSize="18" Text="Svc: "/>
                                                <TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Left" TextWrapping="Wrap"  VerticalAlignment="Top" FontSize="18" Text="{Binding TripService}"/>
                                            </StackPanel>
                                            <StackPanel VerticalAlignment="Top" Orientation="Horizontal">
                                                <TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Left" TextWrapping="Wrap"  VerticalAlignment="Top" FontSize="18" Text="PU: "/>
                                                <TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Left" TextWrapping="Wrap"  VerticalAlignment="Top" FontSize="18" Text="{Binding PURoute}"/>
                                            </StackPanel>
                                            <StackPanel VerticalAlignment="Top" Orientation="Horizontal">
                                                <TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Left" TextWrapping="Wrap"  VerticalAlignment="Top" FontSize="18" Text="DO: "/>
                                                <TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Left" TextWrapping="Wrap"  VerticalAlignment="Top" FontSize="18" Text="{Binding DORoute}"/>
                                            </StackPanel>
                                            <StackPanel VerticalAlignment="Top" Orientation="Horizontal">
                                                <TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Left" TextWrapping="Wrap"  VerticalAlignment="Top" FontSize="18" Text="Pax: "/>
                                                <TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Left" TextWrapping="Wrap"  VerticalAlignment="Top" FontSize="18" Text="{Binding PaxDetails}"/>
                                            </StackPanel>
                                        </StackPanel>
                                    </StackPanel>
                                       <StackPanel x:Name="stknotchecked" VerticalAlignment="Top" Orientation="Vertical">

                                            <StackPanel Orientation="Horizontal">
                                                <Button Background="Gray" Foreground="CadetBlue" VerticalAlignment="Top" Width="300" x:Name="btnaccepttrip" Content="accept trip"></Button>
                                            </StackPanel>
                                            <StackPanel Orientation="Horizontal">
                                                <Button Background="Gray" Foreground="CadetBlue" VerticalAlignment="Top" Width="110" x:Name="btnrejecttrip" Content="reject"></Button>
                                                <Button Background="Gray" Foreground="CadetBlue" VerticalAlignment="Top" Width="110" x:Name="btnshowmap" Content="show map"></Button>
                                            </StackPanel>
                                        </StackPanel>
                                       <StackPanel x:Name="stkaccepted">
                                            <StackPanel Orientation="Horizontal">
                                                <Button Background="Gray" Foreground="CadetBlue" VerticalAlignment="Top" Width="110" x:Name="btndirections" Content="directions"></Button>
                                                <Button Background="Gray" Foreground="CadetBlue" VerticalAlignment="Top" Width="110" x:Name="btnflightinfo" Content="flight info"></Button>
                                            </StackPanel>
                                            <StackPanel Orientation="Horizontal">
                                                <Button Background="Gray" Foreground="CadetBlue" VerticalAlignment="Top" Width="110" x:Name="btndetails" Content="details"></Button>
                                                <Button Background="Gray" Foreground="CadetBlue" VerticalAlignment="Top" Width="110" x:Name="btnlogtimes" Content="log times"></Button>
                                            </StackPanel>
                                            <StackPanel>
                                                <Button x:Name="btnstatus" Content="set status"></Button>
                                            </StackPanel>
                                        </StackPanel>
                                 </StackPanel>
                            </Border>

                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>



    private void addbtncontrols()
    {

        foreach (TripsList lst in TripList.Items)
        {
            ListBoxItem item = TripList.ItemContainerGenerator.ContainerFromItem(lst) as ListBoxItem;
            Button stk = FindFirstElementInVisualTree<Button>(item);
            var stkitem =(Button)stk.FindName("btndirections");
            stkitem.Visibility = Visibility.Collapsed;   
        }
     }

    private T FindFirstElementInVisualTree<T>(DependencyObject parentElement) where T : DependencyObject
    {
        var count = VisualTreeHelper.GetChildrenCount(parentElement);
        if (count == 0)
            return null;

        for (int i = 0; i < count; i++)
        {
            var child = VisualTreeHelper.GetChild(parentElement, i);

            if (child != null && child is T)
            {
                return (T)child;
            }
            else
            {
                var result = FindFirstElementInVisualTree<T>(child);
                if (result != null)
                    return result;

            }
        }
        return null;
      }

Could someone please let me know the way to reslove my issue. Thanks in advance..

2

2 Answers

0
votes

Navigating the visual tree to locate these elements and set their visibility manually is the wrong way to go about solving this problem! I see you are using databinding. Why not expose various properties of type Visibility in the model or view model you are binding to the UI, you can then bind these to the Visibility property of the various UI elements in order to show / hide them.

As an aside, learn about Styles, you XAML has numerous repeated style properties which make it lengthy and hard to follow. You should be able to define a TextBlock style that is applied to all of your TextBlocks to remove much of the repeated code in your question.

0
votes

From the above description, can you provide more information about this:

  1. Where did you invoke addbtncontrol method? If you are responding to an event, let say: Add one more item, then it should be done inside ViewModel.
  2. "your condition": What kind of condition? Can we model it in the Listbox item ViewModel?

I have implemented something the same: Listbox with dynamic items and custom template. Also provide the ability to add new item. So, If you give me more information on what you want to accomplish or better your view model, i can help.