有没有办法根据一个条件选择初始化的布局?我有一个足球统计数据,但如果myViewModel.Sport == Sports.Basketball
我想加载完全不同的布局。
我在每个视图中使用 Datatrigger 尝试过类似的内容,但对我来说这似乎很麻烦:
<Label Text="{Binding Goals}"
Grid.Row="1" Grid.Column="0">
<Label.Triggers>
<DataTrigger TargetType="Label"
Binding="{Binding Sport}"
Value="1">
<Setter Property="Text"
Value="{Binding Points}"/>
</DataTrigger>
</Label.Triggers>
</Label>
我显示“目标”,但如果体育枚举值为1(Sports.Basketball),我会改为“点数”。我想用大量标签甚至图像来做这个,所以我需要一个合适的方法来做到这一点。
有人可以帮助我吗?我需要根据我的ViewModel的Sport属性加载不同的Grid。
答案 0 :(得分:4)
您可以做的另一件事是将每个单独的运动放入其自己的视图中,将所有视图添加到您的页面并根据您想要显示的运动设置其IsVisible属性。
一个例子在伪代码中看起来像这样:
<Page>
<Grid>
<BasketballView IsVisible="{Binding IsBasketball}">
<SoccerView IsVisible="{Binding IsSoccer}">
<FootballView IsVisible="{Binding IsFootball}">
</Grid>
</Page>
然后从ViewModel中设置适当的布尔值。
答案 1 :(得分:0)
要使用DataTemplateSelector
解决此问题,如@StephaneDelcroix所述,您需要一个具有ItemsSource
和ItemTemplate
属性的自定义类。
我还没有考虑/测试过如何将DataTemplateSelector与此结合使用;欢迎任何人将其添加到此答案中。
using System.Collections;
using Xamarin.Forms;
namespace YourNamespace
{
// From https://forums.xamarin.com/discussion/19874/listview-inside-stacklayout-a-height-problem/p2, @maxx313.
public class TemplatedStack : StackLayout
{
public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create("ItemsSource", typeof(IList), typeof(TemplatedStack), propertyChanged: OnItemsSourceChanged);
public IList ItemsSource
{
get { return (IList)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
private static void OnItemsSourceChanged(BindableObject pObj, object pOldVal, object pNewVal)
{
var layout = pObj as TemplatedStack;
if (layout != null && layout.ItemTemplate != null)
{
layout.BuildLayout();
layout.ForceLayout();
}
}
public static readonly BindableProperty ItemTemplateProperty = BindableProperty.Create("ItemTemplate", typeof(DataTemplate), typeof(TemplatedStack), propertyChanged: OnItemTemplateChanged);
public DataTemplate ItemTemplate
{
get { return (DataTemplate)GetValue(ItemTemplateProperty); }
set { SetValue(ItemTemplateProperty, value); }
}
private static void OnItemTemplateChanged(BindableObject pObj, object pOldVal, object pNewVal)
{
var layout = pObj as TemplatedStack;
if (layout != null && layout.ItemsSource != null)
layout.BuildLayout();
}
private void BuildLayout()
{
Children.Clear();
foreach (var item in ItemsSource)
{
var view = (View)ItemTemplate.CreateContent();
view.BindingContext = item;
Children.Add(view);
}
}
protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint)
{
return base.OnMeasure(widthConstraint, heightConstraint);
}
}
}
在您的XAML中,
<yourXmlns:TemplatedStack .../>
其中yourXmlns
必须是XAML顶部的xmlns
声明。
ItemsSource
和ItemTemplate
属性的用法类似于将项目集合和模板绑定到ListView的方式。
(此处不使用ListView
的原因是ListView可能会干扰触摸事件,并增加额外的布局成本。)
为此绑定一个包含单个项目的集合。
例如。对于这个问题,该项目将是正在查看的特定运动。