0

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

corbands
  • 167
  • 1
  • 11

2 Answers2

1

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));
deafjeff
  • 754
  • 7
  • 25
  • If the Template is located in a `ResourceDictionary`, where it should be, you can't set a handler for `Loaded` `Event`. – Novitchi S Jul 03 '13 at 08:48
  • ok. Then you would go via an attached property. The wpf behavior concept is based on those, e.g. look [here](http://stackoverflow.com/questions/10683504/use-of-behavior-in-wpf-mvvm) – deafjeff Jul 03 '13 at 09:20
0

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;
}
Novitchi S
  • 3,711
  • 1
  • 31
  • 44