【问题标题】:Xamarin Forms Binding to Object PropertiesXamarin 窗体绑定到对象属性
【发布时间】:2017-09-25 23:04:49
【问题描述】:

我似乎在 Xamarin Forms 项目中遇到了数据绑定问题。我有两种视图:一种用于列出项目,另一种用于查看详细信息。

列表视图可以很好地加载项目列表及其所有属性,但详细信息页面是空白的并且不会绑定到属性。

列表的视图模型如下所示:

public class MainPageViewModel : ViewModelBase
{
    public MainPageViewModel(IItemService itemService) : base(itemService) { }

    public ObservableCollection<ItemModel> Items { get; set; } = new ObservableCollection<ItemModel>();

    public async override void Start()
    {
        base.Start();

        Items.Clear();

        var results = await service.GetItems();
        foreach (var result in results)
        {
            Items.Add(result);
        }

        IsLoading = false;
    }
}

并且绑定到这个 xaml:

<ListView x:Name="ItemListView" ItemsSource="{Binding Items}" ItemSelected="ItemListView_ItemSelected">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="100" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <StackLayout Orientation="Vertical">
                        <Image Source="{Binding Image}" />
                    </StackLayout>
                    <StackLayout Orientation="Vertical" Grid.Column="1">
                        <Label Text="{Binding Name}" />
                        <Label Text="{Binding Description}" />
                    </StackLayout>
                </Grid>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

再一次,效果很好。

但是细节视图看起来像这样:

public class DetailsPageViewModel : ViewModelBase
{
    public DetailsPageViewModel(IItemService itemService) : base(itemService) { }

    private ItemModel item;
    public ItemModel Item
    {
        get { return item; }
        set
        {
            item = value;
            RaisePropertyChanged();
        }
    }

    protected string ItemId { get; set; }

    public void Init(string itemId)
    {
        this.ItemId = itemId;
    }

    public async override void Start()
    {
        base.Start();

        Item = await service.GetItem(ItemId);

        IsLoading = false;
    }
}

我正在尝试将 ItemModel 属性绑定到详细信息视图上的标签:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MvvmCrossFormsDemo.Views.DetailsPageView">
    <StackLayout>
    <Label Text="{Binding Item.Name}" />
    <Image Source="{Binding Item.Image}" />
    </StackLayout>
</ContentPage>

页面完全空白。

我必须将 INotifyPropertyChanged 添加到我的 ItemModel 吗?如果是这样我不明白为什么,因为ListView绑定相同的模型没有任何需要,那么为什么不能绑定常规标签??

我做错了什么?

【问题讨论】:

    标签: c# xaml mvvm data-binding xamarin.forms


    【解决方案1】:

    您需要先在 ViewModel 中指定属性。 ListView 已经直接绑定到 ViewModel 中的属性,然后 ViewCell 已经绑定到单个项目。

    在详情页中,你是直接绑定到ViewModel的,所以没有Name和Image属性,它们是Item的属性,你需要先指定。

    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="MvvmCrossFormsDemo.Views.DetailsPageView">
        <StackLayout>
            <Label Text="{Binding Item.Name}" />
            <Image Source="{Binding Item.Image}" />
        </StackLayout>
    </ContentPage>
    

    【讨论】:

    • 啊,对了,我确实试过了,但忘了更新我的代码。我确实绑定了 Item.Name 和 Item.Image(不是 ItemModel,因为 Item 是属性的名称,ItemModel 是类型),它仍然不起作用。我用这个 sn-p 更新了原始问题,以表明我正在绑定 details 项目属性,但感谢您指出这一点!
    • 你能在 Set of Item 上设置断点,并确保它被设置了吗?其次,您确定该页面的 BIndingContext 设置正确吗?
    • 好的,是的,谢谢,这就是有趣的地方:我在 get 和 set 上设置了一个断点,然后调用了 get(因为肯定设置了 bindingcontext),在调用 Start 之前它为空。在调用 Start 期间,将调用 set 属性,并使用结果更新 Item 属性。调用了 RaisePropertyChanged,但再也不会调用 GET!也许这个 RaisePropertyChanged 有错误?
    • 啊哈!显然有!我正在使用来自 MvvmCross 的基本 MvxViewModel,它有自己的 INofifyPropertyChanged 实现。当我把它去掉并放入我自己的一个简单的时,它起作用了!所以看起来 MvvmCross 中存在错误,或者我使用错误。如果我能确定问题,我会将您的答案标记为正确,进行一些挖掘,然后发布一个新问题。谢谢!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-14
    相关资源
    最近更新 更多