Dynamic Gridview - 获取第一个子原生广告

Dynamic Gridview - get first child native ads

我有一个简单的动态 Gridview:

<GridView x:Name="MainGridStations" ItemsSource="{x:Bind Stations}" IsItemClickEnabled="True" ItemClick="GridView_ItemClick">
            <GridView.ItemTemplate>
                <DataTemplate x:DataType="local:Station">
                    <Grid>
                        <Grid Background="White" HorizontalAlignment="Center" Width="300" Height="200" VerticalAlignment="Center">
                            <Image x:Name="ImageStation" Source="{Binding ImageURL}"/>
                            <Grid Background="#e4f0fc" Height="65" VerticalAlignment="Bottom" Opacity="0.8">
                                <TextBlock x:Name="StationName" Text="{Binding Name}" FontWeight="Bold" Foreground="#2c9a8b" HorizontalAlignment="Center" />
                            </Grid>
                        </Grid>
                    </Grid>
                </DataTemplate>
            </GridView.ItemTemplate>
</GridView>

现在我想在这个网格视图中使用原生广告。在原生广告的代码中,我需要注册包含点击事件等广告的广告容器。 它将始终是 gridview 的第一个子级,即 gridview 中的第一个网格容器。

我试过这个:

nativeAd.RegisterAdContainer(MainGridStations.ContainerFromIndex(0));

在这里它给了我错误,它不能从 Windows.UI.Xaml.DependencyObject 转换为 Windows.UI.Xaml.FrameworkElement

基本上它需要一个我无法提供的 xaml 控件的直接名称。 我怎样才能克服这个问题?

Here it gives me the error, that it can't convert from Windows.UI.Xaml.DependencyObject to Windows.UI.Xaml.FrameworkElement

RegisterAdContainer 方法注册作为原生广告容器的 UI 元素;这是正确跟踪广告展示次数和点击次数所必需的。

RegisterAdContainer可用参数为FrameworkElement。但是MainGridStations.ContainerFromIndex(0)的值是DependencyObject。所以它会抛出异常。

如果你想在GridView第一项中显示原生广告,你可以在第一项呈现时像下面这样获取第一项。

您需要继承GridView并覆盖MeasureOverrideArrangeOverride方法来获取项目,然后使用Visual Helper获取子项。

class MyGridView : GridView
{
    private const string ImageStation = "ImageStation";
    private const string StationName = "StationName";
    private const string RootLayout = "RootLayout";
    private bool isFirst;

    NativeAdsManagerV2 myNativeAdsManager = null;
    string myAppId = "d25517cb-12d4-4699-8bdc-52040c712cab";
    string myAdUnitId = "test";

    public MyGridView()
    {
        myNativeAdsManager = new NativeAdsManagerV2(myAppId, myAdUnitId);
        myNativeAdsManager.AdReady += MyNativeAd_AdReady;
        myNativeAdsManager.ErrorOccurred += MyNativeAdsManager_ErrorOccurred;
        myNativeAdsManager.RequestAd();
    }

    private void MyNativeAdsManager_ErrorOccurred(object sender, NativeAdErrorEventArgs e)
    {

    }

    private void MyNativeAd_AdReady(object sender, NativeAdReadyEventArgs e)
    {
        NativeAdV2 nativeAd = e.NativeAd;
        AdTitle.Text = nativeAd.Title;
        Adimage.Source = nativeAd.AdIcon.Source;
        nativeAd.RegisterAdContainer(AdContainer);
    }

    protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
    {
        if (this.IndexFromContainer(element) == 0)
        {
            isFirst = true;
        }
        else
        {
            isFirst = false;
        }

        base.PrepareContainerForItemOverride(element, item);
    }


    protected override Size MeasureOverride(Size availableSize)
    {
        return base.MeasureOverride(availableSize);

    }
    private Image Adimage;
    private TextBlock AdTitle;
    private Grid AdContainer;

    protected override Size ArrangeOverride(Size finalSize)
    {
        if (isFirst)
        {
            var item = this.ContainerFromIndex(0);
            AdContainer = MyFindGridViewChildByName(item, RootLayout) as Grid;
            Adimage = MyFindGridViewChildByName(item, ImageStation) as Image;
            AdTitle = MyFindGridViewChildByName(item, StationName) as TextBlock;
            isFirst = false;

        }

        return base.ArrangeOverride(finalSize);
    }

    public static DependencyObject MyFindGridViewChildByName(DependencyObject parant, string ControlName)
    {
        int count = VisualTreeHelper.GetChildrenCount(parant);

        for (int i = 0; i < count; i++)
        {
            var MyChild = VisualTreeHelper.GetChild(parant, i);
            if (MyChild is FrameworkElement && ((FrameworkElement)MyChild).Name == ControlName)
                return MyChild;

            var FindResult = MyFindGridViewChildByName(MyChild, ControlName);
            if (FindResult != null)
                return FindResult;
        }

        return null;
    }

}