corbands
corbands

Reputation: 177

Change element property in code-behind, that described in xaml, DataTemplate

My xaml:

<Style x:Key="grid_image_panel" TargetType="ContentControl">
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <Grid x:Name="image_panel">                       
                    <Image Name="img" Source="Resources/rhcp.jpg" HorizontalAlignment="Center" VerticalAlignment="Center"/>                      
                </Grid>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

I need set event "Tap" for Image "img" in code-behind My C#:

DataTemplate dt = gridy.ContentTemplate as DataTemplate;

DataTemplate dt = gridy.ContentTemplate as DataTemplate;        
Grid grid = dt.LoadContent() as Grid;

Image img = grid.Children.First() as Image;
img.Tap += OnTapped;

Result: tap not worked

Upvotes: 0

Views: 1516

Answers (2)

Novitchi S
Novitchi S

Reputation: 3741

As the docs say:

When you call LoadContent, the UIElement objects in the DataTemplate are created, and you can add them to the visual tree of another UIElement.

This means that, for your code above, when you call LoadContent you will get a new set of UIElements defined in your Template. What you want instead is to get the Image that was already loaded into your ContentControl's visual tree.

You have to get the visual child in order to get your image:

Image img = FindVisualChild<Image>(gridy);
img.Tap += OnTapped;

And this is the FindVisualChild method:

private childItem FindVisualChild<childItem>(DependencyObject obj)
    where childItem : DependencyObject
{

    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
    {

        DependencyObject child = VisualTreeHelper.GetChild(obj, i);

        if (child != null && child is childItem)
            return (childItem)child;
        else
        {
            childItem childOfChild = FindVisualChild<childItem>(child);
            if (childOfChild != null)
               return childOfChild;
        }
    }

    return null;
}

Upvotes: 0

deafjeff
deafjeff

Reputation: 774

ease up things by using e.g. Loaded Event:

        <DataTemplate>
            <Grid x:Name="image_panel">                       
                <Image Name="img" Loaded=OnImgLoaded Source="Resources/rhcp.jpg" HorizontalAlignment="Center" VerticalAlignment="Center" />                      
            </Grid>
        </DataTemplate>

c#:

private void OnImgLoaded(object sender, RoutedEventArgs e)
    {
         // subscribe to your custom Tap event
         (sender as Image).Tap += OnTapped;
    }

you sure have something like:

public static readonly RoutedEvent TapEvent = EventManager.RegisterRoutedEvent(
        "Tap",
        RoutingStrategy.Bubble,
        typeof(RoutedEventHandler),
        typeof(MyClass));

Upvotes: 1

Related Questions