XamlBindingHelper类

时间:2017-07-03 21:27:15

标签: c# uwp uwp-xaml xbind

有人可以通过示例提供XamlBindingHelper类使用的概述吗?特别是GetDataTemplateComponentSetDataTemplateComponent方法。

1 个答案:

答案 0 :(得分:2)

在官方document中,它说

  

此类用于由XAML编译器生成的代码。

这告诉我,我应该能够在.g.cs的代码生成的类(x:Bind)中找到它的一些参考,因为互联网上没有一个单独的线程解释它究竟是做什么的。

所以我创建了一个带有ListView的测试UWP项目,并在其ItemTemplate内部使用x:Bind投入了一些x:Phase。编译完项目后,我发现我的MainPage.g.cs -

中使用了一些方法

<强> XamlBindingHelper.ConvertValue

public static void Set_Windows_UI_Xaml_Controls_ItemsControl_ItemsSource(global::Windows.UI.Xaml.Controls.ItemsControl obj, global::System.Object value, string targetNullValue)
{
    if (value == null && targetNullValue != null)
    {
        value = (global::System.Object) global::Windows.UI.Xaml.Markup.XamlBindingHelper.ConvertValue(typeof(global::System.Object), targetNullValue);
    }
    obj.ItemsSource = value;
}

显然XamlBindingHelper.ConvertValue方法用于转换值。我已经知道了这一点,因为我在最近的答案one中使用了它。

XamlBindingHelper.SuspendRendering &amp;的 XamlBindingHelper.ResumeRendering

public int ProcessBindings(global::Windows.UI.Xaml.Controls.ContainerContentChangingEventArgs args)
{
    int nextPhase = -1;
    switch(args.Phase)
    {
        case 0:
            nextPhase = 1;
            this.SetDataRoot(args.Item);
            if (!removedDataContextHandler)
            {
                removedDataContextHandler = true;
                ((global::Windows.UI.Xaml.Controls.StackPanel)args.ItemContainer.ContentTemplateRoot).DataContextChanged -= this.DataContextChangedHandler;
            }
            this.initialized = true;
            break;
        case 1:
            global::Windows.UI.Xaml.Markup.XamlBindingHelper.ResumeRendering(this.obj4);
            nextPhase = -1;
            break;
    }
    this.Update_((global::System.String) args.Item, 1 << (int)args.Phase);
    return nextPhase;
}

public void ResetTemplate()
{
    this.bindingsTracking.ReleaseAllListeners();
    global::Windows.UI.Xaml.Markup.XamlBindingHelper.SuspendRendering(this.obj4);
}

XamlBindingHelper.SuspendRendering&amp; XamlBindingHelper.ResumeRendering看起来非常有趣。它们似乎是启用ListView / GridView增量项呈现的关键功能,有助于改善整体平移/滚动体验。

除了x:DeferLoadingStrategyx:Load创作者更新)之外,它们还可用于改善您的应用效果。

IDataTemplateComponent &amp; IDataTemplateExtension

但是,我找不到与GetDataTemplateComponentSetDataTemplateComponent相关的任何内容。我甚至尝试在XAML中手动设置此附加属性,但 get 方法始终返回null

这是有趣的一点。我后来在生成的类中找到了这段代码。

case 2: // MainPage.xaml line 13
    {                    
        global::Windows.UI.Xaml.Controls.Grid element2 = (global::Windows.UI.Xaml.Controls.Grid)target;
        MainPage_obj2_Bindings bindings = new MainPage_obj2_Bindings();
        returnValue = bindings;
        bindings.SetDataRoot(element2.DataContext);
        element2.DataContextChanged += bindings.DataContextChangedHandler;
        global::Windows.UI.Xaml.DataTemplate.SetExtensionInstance(element2, bindings);
    }
    break;

方法DataTemplate.SetExtensionInstance看起来与XamlBindingHelper.SetDataTemplateComponent非常相似。它需要element2 Grid ItemTemplate中的ListViewDataTemplate.SetExtensionInstanceIDataTemplateExtension;后者采用元素和IDataTemplateComponent。如果你看一下它们的定义,它们的功能非常相似,这让我想到XamlBindingHelper.SetDataTemplateComponentIDataTemplateComponent的替代?如果不这样的话,我很想知道。

IDataTemplateExtension不同,您可以在代码中获取var firstItemContainer = (ListViewItem)MyListView.ContainerFromIndex(0); var rootGrid = (Grid)firstItemContainer?.ContentTemplateRoot; var dataTemplateEx = DataTemplate.GetExtensionInstance(rootGrid); 的实例 -

dataTemplateEx

就我而言,MainPage_obj2_Bindings是另一个名为ResetTemplate的生成类的实例,您可以访问ProcessBindings<html ng-app="plunker"> <head> <script data-require="angular.js@1.2.x" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js" data-semver="1.2.16"></script> </head> <body ng-controller="MainCtrl"> <table> <tr ng-repeat="subscription in entities"> <td> <input type="radio" ng-model="subscription.checked" ng-value="true" ng-click="updateSelection($index, entities)" />{{subscription.name}} </td> </tr> </table> </body> <script> var app = angular.module('plunker', []); app.controller('MainCtrl', function($scope, $http, $location, $window) { $scope.entities = [{ name: 'Last Week', id: 1, checked: false }, { name: 'Last Month', id: 2, checked: false }, { name: 'Last year', id: 3, checked: false }, { name: 'Last 3 months', id: 4, checked: false }, { name: 'Last 6 months', id: 5, checked: false }, { name: 'Last 9 months', id: 6, checked: false } ] $scope.updateSelection = function(position, entities) { angular.forEach(entities, function(subscription, index) { if (position != index) subscription.checked = false; else { console.log(subscription.id); $window.location.href = "/view_report/?q=" + subscription.id; } }); }; }); </script> 等方法。

我认为如果您要构建自己的自定义列表控件,它们可能会有所帮助,但除此之外,我无法理解您为何需要它们。