VisualTree - lucyberryhub/WPF.Tutorial GitHub Wiki

πŸ’ Visual Tree Adventures + Cherry Changes! πŸ’

Hey cutie! πŸ“ It’s your girl Lucy Berry again, and I’ve got some super fun news for you today! πŸ’– We're going on a Visual Tree Adventure where we will find the little cherries πŸ’ inside the button and give them a fabulous makeover! ✨

You already know how to change a cherry’s image when you click the delete button πŸ’πŸ“, but today, we’re going to find the image inside the button by exploring the visual tree of the button! 🌸

πŸ’ What’s a Visual Tree, you ask? πŸ’

A visual tree is like a magical forest πŸƒ where all the visual elements of your UI live (like Buttons, Images, TextBoxes, and more!). 🌟 We’re going to use the FindVisualChild method to find the image hidden deep inside a button πŸŒΊβ€”just like discovering the juiciest berry at the bottom of a basket! πŸ“βœ¨


Step 1: Setting the Stage – The Button & Image πŸ’πŸ“

First, we have our cute Button with an image inside. πŸ’ Let’s imagine that when we click on the button, we want to find the image and set it to a preview area (like a basket where we showcase our favorite cherries πŸ“).

Here’s the super fun part! We’re going to use FindVisualChild to look inside the button and find the Image element, and then we’ll update our ImagePreview02 with it. πŸ’

Here’s how we do it in the cutest and most professional way possible πŸ“βœ¨:


Step 2: The Code that Makes It All Happen πŸ’

Now, it’s time for the fun part! Let’s write the code that will help us find the cherry (image) and showcase it in the preview πŸ’:

private void OnCherryImageButtonClick(object sender, RoutedEventArgs e)
{
    if (sender is Button cherryButton)
    {
        // Find the Image inside the button by searching its visual tree πŸ’
        var cherryImage = ObjectsHelper.FindVisualChild<Image>(cherryButton);

        if (cherryImage != null)
        {
            // Get the ImageSource from the clicked cherry image πŸ“
            ImageSource selectedCherryImage = cherryImage.Source;

            // Set it to ImagePreview02 πŸ’
            ImagePreview02.Source = selectedCherryImage;
        }
    }
}

Now, let's break it down, step by step! πŸ’βœ¨


Step 3: How Does the Code Work? πŸ“

Step 1: The Cherry Button πŸ’

We start by making sure we clicked on the Button (which holds our cherry image πŸ’). If we clicked the button, we’re ready to go! πŸ“

if (sender is Button cherryButton)

Step 2: Searching the Visual Tree πŸ’

Once we have the button, we use the FindVisualChild method to look inside the button and find the Image! It’s like searching for the cherry πŸ’ hidden under the leaves in a garden. πŸ“

var cherryImage = ObjectsHelper.FindVisualChild<Image>(cherryButton);

Step 3: Set the Image to ImagePreview02 πŸ’

After finding the image, we grab the ImageSource and set it to ImagePreview02. Now, you can see the cute cherry πŸ’ in the preview area!

ImagePreview02.Source = selectedCherryImage;

Step 4: The Magical FindVisualChild Method πŸ’

You might be wondering, Lucy, how does this magic work? How do we find the cherry inside the button? πŸ’πŸ’–

Here’s the FindVisualChild method that helps us find any child element in the visual tree! 🌸

public static T FindVisualChild<T>(DependencyObject parent) where T : DependencyObject
{
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
    {
        var child = VisualTreeHelper.GetChild(parent, i);
        if (child is T)
        {
            return (T)child;  // We found our cherry! πŸ’
        }
        else
        {
            var foundChild = FindVisualChild<T>(child);
            if (foundChild != null)
            {
                return foundChild;  // Keep looking if it’s not the cherry yet! πŸ“
            }
        }
    }
    return null;  // No cherry found! πŸ“
}

Let’s go through how FindVisualChild works: 🌸

  • Step 1: We start by looking at all the children of the parent element (in our case, the Button).

  • Step 2: If one of the children is the Image we’re looking for (the cherry πŸ’), we return it!

  • Step 3: If the child isn’t an image, we continue searching the tree deeper until we find our cherry!

  • Step 4: If we don’t find the cherry, we return null πŸ“.


Step 5: Bringing It All Together πŸ’

Now, let’s combine everything we’ve learned into a super fun, cutie pie solution πŸ“βœ¨:

  1. When you click on a button (cherry πŸ’), we will find the image inside the button.
  2. If we find the image, we will update the ImagePreview02 with this sweet cherry! πŸ’

Here’s the final code to make it all work:

private void OnCherryImageButtonClick(object sender, RoutedEventArgs e)
{
    if (sender is Button cherryButton)
    {
        // Find the Image inside the button by searching its visual tree πŸ’
        var cherryImage = ObjectsHelper.FindVisualChild<Image>(cherryButton);

        if (cherryImage != null)
        {
            // Get the ImageSource from the clicked cherry image πŸ“
            ImageSource selectedCherryImage = cherryImage.Source;

            // Set it to ImagePreview02 πŸ’
            ImagePreview02.Source = selectedCherryImage;
        }
    }
}

Step 6: Bonus - The Cherry on Top πŸ’πŸ“

Now that we have found the cherry inside the button and changed the image, let's add our delete cherry functionality from earlier. πŸ’– When you click on the delete button, it will also update another cherry πŸ’!

Here’s how to do both things together! πŸ“

private void OnDeleteCherryButtonClick(object sender, RoutedEventArgs e)
{
    if (sender is Button cherryButton && cherryButton.DataContext is CherryBerryModel selectedCherry)
    {
        // Change the selected cherry's image to a "Plus" cherry
        byte[] cherryImageBytes = Convert.FromBase64String(AppDbConfig.CherryPlusImage);
        selectedCherry.Image = new BerryBlob(cherryImageBytes);

        // Find the cherry with the ID + 6 and change its image to "Empty" cherry
        var targetCherry = cherryBasket.FirstOrDefault(cherry => cherry.Id == selectedCherry.Id + 6);
        
        // If the cherry exists, set the image to "Empty"
        if (targetCherry != null)
        {
            byte[] emptyCherryImageBytes = Convert.FromBase64String(AppDbConfig.EmptyCherryImage);
            targetCherry.Image = new BerryBlob(emptyCherryImageBytes);
        }

        // Bonus! Also find the image inside the button πŸ’
        OnCherryImageButtonClick(sender, e);  // Reuse the cherry image find function!
    }
}
⚠️ **GitHub.com Fallback** ⚠️