Xamarin Forms-UWP自定义渲染器:如何将子项添加到堆栈布局

时间:2018-07-29 12:52:32

标签: xamarin.forms uwp

我正在尝试在StackLayout的自定义渲染器中插入特定于UWP的子级。 但是,在下面的示例代码中,Control始终为null,而我的StackLayout有子级。也许StackPanel不是UWP中呈现的StackLayout

public class MyRenderer : ViewRenderer<StackLayout, StackPanel>
{
    private bool _childAdded;

    protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (!_childAdded && Control?.Children != null)
        {
            _childAdded = true;
            Control.Children.Insert(0, new Windows.UI.Xaml.Shapes.Rectangle());
        }
        base.OnElementPropertyChanged(sender, e);
    }
}

3 个答案:

答案 0 :(得分:0)

您在cade中进行了一些修改,因为您在代码实现后调用了 base.OnElementPropertyChanged(sender,e)。只需尝试使用下面的代码即可。

public class MyRenderer : ViewRenderer<StackLayout, StackPanel>
{
    private bool _childAdded;

    protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
         base.OnElementPropertyChanged(sender, e);
         if(Control==null)
          return;
        if (!_childAdded && Control.Children != null)
        {
            _childAdded = true;
            Control.Children.Insert(0, new Windows.UI.Xaml.Shapes.Rectangle());
        }

    }
}

答案 1 :(得分:0)

StackLayoutLayout)渲染器是ViewRenderer,由FrameworkElement在UWP上实现; Renderer Base Classes and Native Controls

理论渲染器:

public class MyRenderer : ViewRenderer<StackLayout, FrameworkElement>
...

答案 2 :(得分:0)

  

Control始终为null,而我的StackLayout具有Children。也许是StackPanel。

源自official document

  

在Xamarin.Forms中,所有布局类均从Layout<T>类派生,并将泛型限制为View及其派生类型。但是children元素的布局不正确。

并且UWP平台中的匹配本机控件为LayoutRenderer。因此,它不是直接继承StackPanel。您还可以像下面这样自定义定制器。

[assembly: ExportRenderer(typeof(StackLayout), typeof(ICustomStackLayoutRenderer))]

namespace CustomStackLayoutRenderer.UWP
{
    public class ICustomStackLayoutRenderer : ViewRenderer<StackLayout, StackPanel>
    {
        private bool _childAdded;
        protected override void OnElementChanged(ElementChangedEventArgs<StackLayout> e)
        {
            base.OnElementChanged(e);
            if (Control == null)
            {
                var stacklayout = new StackPanel();
                SetNativeControl(stacklayout);
            }
            if (e.OldElement != null)
            {

            }
            if (e.NewElement != null)
            {
                if (!_childAdded && Control.Children != null)
                {
                    _childAdded = true;
                    Control.Children.Insert(0, new Windows.UI.Xaml.Shapes.Rectangle() { Width = 100, Height = 100, Fill = new SolidColorBrush(Colors.Red) });
                }
            }

        }
    }
}

根据您的要求,更好的方法是在CustomStackLayout中创建一个StackLayout继承Xamarin.Forms,然后在您的LayoutChildren覆盖方法中重新布局子元素。有关更多详细信息,请参阅Creating a Custom Layout