【问题标题】:Xamarin Forms - UWP custom renderer: how to add a child to a stacklayoutXamarin Forms - UWP 自定义渲染器:如何将子级添加到 stacklayout
【发布时间】:2019-01-05 21:50:04
【问题描述】:

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

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

【问题讨论】:

    标签: xamarin.forms uwp


    【解决方案1】:

    你的一些修改是 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());
            }
    
        }
    }
    

    【讨论】:

    • Tks,但我看不出从基本实现开始会有什么改变。但是,您让我意识到这不是Children,而是null,而是Control。因此,问题肯定是 UWP 中的 StackLayout 实现可能不是 StackPanel
    【解决方案2】:

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

    理论渲染器:

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

    【讨论】:

      【解决方案3】:

      Control 始终为空,而我的 StackLayout 有子项。也许是 StackPanel。

      派生自official document

      在 Xamarin.Forms 中,所有布局类都派生自 Layout&lt;T&gt; 类,并将泛型类型限制为 View 及其派生类型。但是子元素的布局不正确。

      UWP平台内匹配的Native控件为LayoutRenderer。所以它不是直接继承StackPanel。你也可以像下面这样自定义一个customerrederer。

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-04-15
        • 2018-07-29
        • 2020-03-16
        • 2018-01-04
        • 2016-09-03
        • 2018-07-23
        • 1970-01-01
        • 2014-10-26
        相关资源
        最近更新 更多