Search code examples
c#wpflistboxcontrolslistboxitem

Accessing Controls in ListboxItem


I have a ListBox. This ListBox has custom controls. For example, image, textblocks, etc. Initially textblocks are collapsed, image is visible. I want to make the textblocks visible when user enter with mouse and change opacity of image in that item. But I can't access listboxitems controls. I named them but they don't show up.How can I achieve that ? My ListBox XAML codes:

<ListBox SelectionChanged="MoviesDisplay_OnSelectionChanged" ScrollViewer.HorizontalScrollBarVisibility="Disabled" Background="Black" x:Name="MoviesDisplay">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid  x:Name="MoviesGrid"  Height="355" Width="240" Margin="10,20,20,3" HorizontalAlignment="Left">
                        <Image x:Name="MoviePoster" Opacity="1" Source="{Binding Poster}"></Image>
                        <TextBlock Visibility="Collapsed" x:Name="MovieName" FontSize="18" Text="{Binding Name}" Foreground="White" Margin="0,15,0,321"></TextBlock>
                        <TextBlock Visibility="Collapsed" x:Name="MovieGenre" FontSize="16" Text="" Foreground="White" Margin="0,34,0,302"></TextBlock>
                        <TextBlock Visibility="Collapsed" x:Name="MovieReleaseDate" FontSize="16" Text="{Binding ReleaseDate}" Foreground="White" Margin="0,53,164,284"></TextBlock>
                        <materialDesign:RatingBar Visibility="Collapsed" Foreground="White"
                                                  Value="{Binding Rating}"
                                                  x:Name="MovieRatingBar" Margin="59,314,60,17"
                        />
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel IsItemsHost="True" Orientation="Horizontal"  />
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
        </ListBox>







private async void Window_Loaded(object sender, RoutedEventArgs e)
    {
        client.GetConfig();
        var popularMovies = await client.GetMoviePopularListAsync("en", 1);
        PopularMovies.Clear();
        foreach (var movie in popularMovies.Results)
        {
           // ImgListUrls.Add(client.GetImageUrl("w500",movie.PosterPath).AbsoluteUri);
            Movie mov = new Movie()
            {
                Id = movie.Id,
                Name = movie.OriginalTitle,
                ReleaseDate = movie.ReleaseDate.Value.ToShortDateString(),
                Poster = client.GetImageUrl("w500", movie.PosterPath).AbsoluteUri,
                Rating = movie.VoteAverage
            };

            PopularMovies.Add(mov);

        }
        MoviesDisplay.ItemsSource = PopularMovies; 
       // DownloadImages(ImgListUrls);
    }

Solution

  • You don't need to access these elements in code behind. Add Styles with DataTriggers instead, e.g.:

    <Image Source="{Binding Poster}">
        <Image.Style>
            <Style TargetType="Image">
                <Setter Property="Opacity" Value="1"/>
                <Style.Triggers>
                    <DataTrigger
                        Binding="{Binding IsMouseOver,
                                  RelativeSource={RelativeSource AncestorType=ListBoxItem}}"
                        Value="True">
                        <Setter Property="Opacity" Value="0.5"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Image.Style>
    </Image>
    

    Put the TextBlocks in a StackPanel and add a similar Style:

    <StackPanel>
        <StackPanel.Style>
            <Style TargetType="StackPanel">
                <Setter Property="Visibility" Value="Collapsed"/>
                <Style.Triggers>
                    <DataTrigger
                        Binding="{Binding IsMouseOver,
                                  RelativeSource={RelativeSource AncestorType=ListBoxItem}}"
                        Value="True">
                        <Setter Property="Visibility" Value="Visible"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </StackPanel.Style>
        <TextBlock FontSize="18" Text="{Binding Name}" Foreground="White"/>
        <TextBlock FontSize="16" Text="{Binding ReleaseDate}" Foreground="White"/>
    </StackPanel>