【问题标题】:Change element property in code-behind, that described in xaml, DataTemplate在 xaml、DataTemplate 中描述的代码隐藏中更改元素属性
【发布时间】:2013-07-03 16:55:27
【问题描述】:

我的xml:

<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>

我需要在代码隐藏中为图像“img”设置事件“Tap” 我的 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;

结果:点击无效

【问题讨论】:

    标签: .net wpf xaml datatemplate code-behind


    【解决方案1】:

    通过使用例如加载事件:

            <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;
        }
    

    你肯定有类似的东西:

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

    【讨论】:

    • 如果模板位于应该在的ResourceDictionary 中,则不能为Loaded Event 设置处理程序。
    • 好的。然后你会通过一个附加的属性。 wpf 行为概念基于这些,例如看here
    【解决方案2】:

    正如文档所说:

    当您调用 LoadContent 时,DataTemplate 中的 UIElement 对象被创建,您可以将它们添加到另一个 UIElement 的可视化树中。

    这意味着,对于您上面的代码,当您调用 LoadContent 时,您将获得一组在您的 Template 中定义的新 UIElement。相反,您想要的是获取已经加载到您的 ContentControl's 视觉树中的图像。

    你必须得到视觉孩子才能得到你的形象:

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

    这就是FindVisualChild 方法:

    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;
    }
    

    【讨论】:

      猜你喜欢
      • 2012-08-03
      • 2019-06-07
      • 2011-08-03
      • 2012-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多