Xamarin 形成 MVVM Stacklayout 内容绑定
Posted
技术标签:
【中文标题】Xamarin 形成 MVVM Stacklayout 内容绑定【英文标题】:Xamarin forms MVVM Stacklayout content binding 【发布时间】:2017-05-10 09:30:43 【问题描述】:我对 Xamarin 和 Xamarin 表单非常陌生,我需要一些帮助。
我有一个 StackLayout,我想从我的 ViewModel 中动态添加项目。问题是我似乎无法将 StackLayout 的内容绑定到我的 ViewModel 的 StackLayout。
这是我认为的 xaml 代码
<StackLayout/>
我想要类似的东西
<StackLayout Content="Binding MainStackLayout"/>
我的 ViewModel 中已经像这样设置了 StackLayout
public StackLayout MainStackLayout;
【问题讨论】:
【参考方案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" <local:BindableStackLayout Items="Binding YourItemCollection" />
一个小问题。 “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下载源码
【讨论】:
以上是关于Xamarin 形成 MVVM Stacklayout 内容绑定的主要内容,如果未能解决你的问题,请参考以下文章