VisualTree - lucyberryhub/WPF.Tutorial GitHub Wiki
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! πΈ
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! πβ¨
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 πβ¨:
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 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;
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 π.
Now, letβs combine everything weβve learned into a super fun, cutie pie solution πβ¨:
- When you click on a button (cherry π), we will find the image inside the button.
- 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;
}
}
}
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!
}
}