【问题标题】:Xamarin forms MVVM Stacklayout content bindingXamarin 形成 MVVM Stacklayout 内容绑定
【发布时间】:2017-05-10 09:30:43
【问题描述】:

我对 Xamarin 和 Xamarin 表单非常陌生,我需要一些帮助。

我有一个 StackLayout,我想从我的 ViewModel 中动态添加项目。问题是我似乎无法将 StackLayout 的内容绑定到我的 ViewModel 的 StackLayout。

这是我认为的 xaml 代码

<StackLayout/>

我想要类似的东西

<StackLayout Content="{Binding MainStackLayout}"/>

我的 ViewModel 中已经像这样设置了 StackLayout

public StackLayout MainStackLayout;

【问题讨论】:

    标签: c# mvvm xamarin.forms


    【解决方案1】:

    你必须编写一个 UI 组件。

    using Xamarin.Forms;
    
    using System.Collections.Specialized;
    using System.ComponentModel;
    
    class BindableStackLayout : StackLayout
    {
        public static readonly BindableProperty ItemsProperty =
            BindableProperty.Create(nameof(Items), typeof(ObservableCollection<View>), typeof(BindableStackLayout), null,
                propertyChanged: (b, o, n) =>
                {
                    (n as ObservableCollection<View>).CollectionChanged += (coll, arg) =>
                    {
                        switch (arg.Action)
                        {
                            case NotifyCollectionChangedAction.Add:
                                foreach (var v in arg.NewItems)
                                    (b as BindableStackLayout).Children.Add((View)v);
                                break;
                            case NotifyCollectionChangedAction.Remove:
                                foreach (var v in arg.NewItems)
                                    (b as BindableStackLayout).Children.Remove((View)v);
                                break;
                            case NotifyCollectionChangedAction.Move:
                                //Do your stuff
                                break;
                            case NotifyCollectionChangedAction.Replace:
                                //Do your stuff
                                break;
                        }
                    };
                });
    
    
        public ObservableCollection<View> Items
        {
            get { return (ObservableCollection<View>)GetValue(ItemsProperty); }
            set { SetValue(ItemsProperty, value); }
        }
    }
    

    【讨论】:

    • 我真的很困惑,我应该如何在 XAML 中使用它
    • xmlns:local="clr-namespace:yourNamespace;assembly=yourAssembly" &lt;local:BindableStackLayout Items="{Binding YourItemCollection}" /&gt;
    • 一个小问题。 “YourItemCollection”是什么类型的?我的意思是它是否绑定到另一个 StackLayout 或 A Dictionary of items
    • 没关系,我让它工作了。非常感谢你拯救了我的一天!
    • 嘿! @TarekAdel,您能否分享有关您如何解决此问题的更多详细信息?我正在尝试将 UI 元素动态添加到 stackLayout。
    【解决方案2】:

    只需使用 BindableLayout:https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/layouts/bindable-layouts

    <StackLayout BindableLayout.ItemsSource="{Binding Items}">
        <BindableLayout.ItemTemplate>
            <DataTemplate>
                <Label Text="{Binding Title}" />
            </DataTemplate>
        </BindableLayout.ItemTemplate>
    </StackLayout>
    

    它支持ItemsSource、ItemTemplate和ItemTemplateSelector。

    【讨论】:

      【解决方案3】:

      想要为您的 stacklayout 提供不同尺寸的可绑定 itemsource 我制作的自定义 contentview 将帮助您实现它:)

      using System;
      using System.Collections;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      
      using Xamarin.Forms;
      /*
      this class will help you to have bindable children with different sizes for the stacklayout with scrollview 
      in you xaml add 
          <UIControls:SAStackLayout ItemsSource="{Binding YourDataSource}"  Orientation="Horizontal">
                                  <DataTemplate>
                                      <Grid>
                                          <Label Text="{Binding Name}" Margin="15,0" HorizontalOptions="Center" VerticalOptions="Center"    FontSize="Small"  VerticalTextAlignment="Center" HorizontalTextAlignment="Center" TextColor="White"/>
                                      </Grid>
                                  </DataTemplate>
         </UIControls:SAStackLayout>
      
       */
      namespace Shop.UI.Controls
      {
          [ContentProperty("ItemContent")]
          public class SAStackLayout : ContentView
          {
              private ScrollView _scrollview;
              private StackLayout _stacklayout { get; set; }
              public SAStackLayout()
              {
                  _stacklayout = new StackLayout();
                  _scrollview = new ScrollView()
                  {
                      Content = _stacklayout
                  };
                  Content = _scrollview;
              }
              public static readonly BindableProperty ItemContentProperty = BindableProperty.Create("ItemContent", typeof(DataTemplate), typeof(SAStackLayout), default(ElementTemplate));
      
              public DataTemplate ItemContent
              {
                  get { return (DataTemplate)GetValue(ItemContentProperty); }
                  set { SetValue(ItemContentProperty, value); }
              }
      
      
              private ScrollOrientation _scrollOrientation;
              public ScrollOrientation Orientation
              {
                  get
                  {
                      return _scrollOrientation;
                  }
                  set
                  {
                      _scrollOrientation = value;
                      _stacklayout.Orientation = value == ScrollOrientation.Horizontal ? StackOrientation.Horizontal : StackOrientation.Vertical;
                      _scrollview.Orientation = value;
                  }
              }
      
              public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create("ItemsSource", typeof(IEnumerable), typeof(SAStackLayout), default(IEnumerable), propertyChanged: GetEnumerator);
              public IEnumerable ItemsSource
              {
                  get { return (IEnumerable)GetValue(ItemsSourceProperty); }
                  set { SetValue(ItemsSourceProperty, value); }
              }
      
              private static void GetEnumerator(BindableObject bindable, object oldValue, object newValue)
              {
                  foreach (object child in (newValue as IEnumerable))
                  {
                      View view = (View)(bindable as SAStackLayout).ItemContent.CreateContent();
                      view.BindingContext = child;
                      (bindable as SAStackLayout)._stacklayout.Children.Add(view);
                  }
              }
          }
      }
      

      here下载源码

      【讨论】:

        猜你喜欢
        • 2018-07-14
        • 1970-01-01
        • 1970-01-01
        • 2020-07-15
        • 2019-01-18
        • 1970-01-01
        • 1970-01-01
        • 2016-09-25
        • 2020-03-21
        相关资源
        最近更新 更多