使用Observable Collection MVVM绑定透视图控件(Windows Phone 8) [英] Binding Pivot control with Observable Collection MVVM (windows phone 8)

查看:88
本文介绍了使用Observable Collection MVVM绑定透视图控件(Windows Phone 8)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是WP8&的新手. MVVM.我创建了wp8应用程序,该应用程序在用户登录后会请求各种数据.我只是无法获取动态创建的数据透视表头,而且我不知道是否是因为我在绑定中进行了某些操作, INotifyPropertyChanged,两者或其他!!

I'm new to WP8 & MVVM. I created wp8 app which requests various bits of data once a user has logged in. I just can't get my pivots header to get created dynamically and I don't know if it is because I'm doing something in the binding, the INotifyPropertyChanged, both or something else!!

这是我到目前为止所做的:

Here is what I have done so far:

我在App.cs中定义了一个全局MainViewModel,它将存储登录时返回的所有数据.

I've got a global MainViewModel defined in App.cs which will stored all the data returned at login time.

一旦登录成功并且数据已经加载到MainViewModel中,我将其重定向到包含Pivot控件的测试页面,并且尝试动态创建Pivot项.

Once the login is successful and the data has been loaded into the MainViewModel, I redirect this to a test page which contains a Pivot Control and I'm trying to create Pivot Items dynamically.

这是我的测试页的xaml,即MainPivotPage.xaml和我的MainPivotViewModel被初始化,因为它被定义为本地资源并被设置为Pivot控件的datacontext,我不知道我是否正在这样做是的,但是我正在将"Name"属性分配给PivotItem的页眉,PivotItem的页眉是存储在我的可观察集合Pivots中的对象.属性Name是我在名为Pivot的类中拥有的2个属性之一,该类包含PivotId和Name.

This is the xaml for my test page i.e. MainPivotPage.xaml and my MainPivotViewModel is initialized as it is defined as a local resource and is set as the datacontext for the Pivot control and I don't know if I'm doing this right but I'm assigning the "Name" property to the Header of the PivotItem which are the object stored in my observable collection Pivots. The property Name is one of the 2 properties I have in a Class called Pivot which contains PivotId and Name.

<phone:PhoneApplicationPage
    x:Class="TestApp.Views.MainPivotPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:viewModel="clr-namespace:TestApp.ViewModels"
    mc:Ignorable="d"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait"  Orientation="Portrait"
    shell:SystemTray.IsVisible="True" Loaded="PhoneApplicationPage_Loaded">
    <!--LayoutRoot is the root grid where all page content is placed-->

    <phone:PhoneApplicationPage.Resources>
        <viewModel:MainPivotViewModel x:Key="MainPivotViewModel" />
    </phone:PhoneApplicationPage.Resources>

    <Grid x:Name="LayoutRoot" Background="Transparent">
        <!--Pivot Control-->
        <phone:Pivot Title="My Search Options" x:Name="MainPivots" ItemsSource="{Binding Pivots}" DataContext="{StaticResource MainPivotViewModel}">
            <phone:PivotItem Header="{Binding Name}">
                <!--<Grid/>-->
            </phone:PivotItem>
        </phone:Pivot>
    </Grid>
</phone:PhoneApplicationPage>

创建MainPivotViewModel时,我将Pivots可观察集合设置为与存储在我的MainViewModel中的可观察集合相同,该可观察集合包含登录时返回的所有数据.如您所见,我将其分配给属性而不是内部变量,以确保它将触发INotifyPropertyChanged(嗯,我认为)

When the MainPivotViewModel is created, I set the Pivots observable collection to the same observable collection stored in my MainViewModel which contains all the data returned at logon. As you can see I assign it to the property rather than the internal variable to ensure that it will trigger the INotifyPropertyChanged (well..., I think)

public class MainPivotViewModel : BaseViewModel
{
    private ObservableCollection<Pivot> _pivots = null;

    public MainPivotViewModel()
    {
        Pivots = App.MainViewModel.Pivots;            
    }

    public ObservableCollection<Pivot> Pivots
    {
        get
        {
            return _pivots;
        }

        set
        {
            if (_pivots != value) this.SetProperty(ref this._pivots, value);
        }
    }
}

我使用基类中包含的SetProperty函数,该函数用于生成INotifyPropertyChanged事件,并允许我每次设置INotifyPropertyChanged事件时都无需设置属性名.

I use the SetProperty function which is contained in my base class and is used to generate the INotifyPropertyChanged event and allows me to do so without having the set the property name every time I need to the INotifyPropertyChanged event.

这是我的BaseView的代码:

This is the code for my BaseView:

public class BaseViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] String propertyName = null)
    {
        if (object.Equals(storage, value)) return false;

        storage = value;
        this.OnPropertyChanged(propertyName);
        return true;
    }

    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var eventHandler = this.PropertyChanged;
        if (eventHandler != null)
        {
            eventHandler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

我的Pivot类如下:

My Pivot class looks like this:

public class Pivot: BaseModel
{
    private int _pivotId;
    private string _name = string.Empty;

    public Pivot()
    {

    }

    public Pivot(int pivotId, string name)
    {
        PivotId = pivodId;
        Name = name;
    }

    public int PivotId
    {
        get { return _pivotId; }
        set { if (_pivotId != value) this.SetProperty(ref this._pivotId, value); }
    }

    public string Name
    {
        get { return _name; }
        set { if (_name != value) this.SetProperty(ref this._name, value); }
    }
}

您可能会注意到,这是从BaseModel继承的.这与BaseViewModel中的代码完全相同,但是我想将两者分开.我不确定在我的Pivot类上是否需要这样做,但是我尝试了不同的方案,暂时将其保留.

You may notice that this one is inheriting from BaseModel. This is exactly the same code as in BaseViewModel but I wanted to keep the two separate. I'm not event sure this is needed on my Pivot class, but I was trying different scenario and left it in for now.

我不知道我在做什么错,但是无论我怎样尝试,我都无法将"Name"属性显示为Header的文本.我很确定将MainPivotViewModel分配为本地资源时会对其进行初始化,因为它正确地调用了我的构造函数,然后初始化了我的可观察集合,但就目前为止.

I don't know what I'm doing wrong, but no matter what I try I can't get the "Name" property to be displayed as the Header's text. I'm pretty sure the MainPivotViewModel is initialized when it is assigned as a local resource as I it's calling my constructor correctly which is then initializing my observable collection but that's as far as it goes.

但是它什么也没显示!

我注意到的另一件事是,当我在BaseViewModel类的OnPropertyChanged方法的"Set"中放置断点时,eventHandler始终为null,无论我认为不应该是哪种情况,但我不能看看我在做什么错.

Another thing I've noticed is when I put breakpoints in the "Set" in OnPropertyChanged method in the BaseViewModel class, the eventHandler is always null, no matter what which I assume should not be the case, but I can't see what I'm doing wrong.

我有很多关于stackoverflow的文章,还有其他文章,只是看不到我做错了什么?任何人有任何想法吗?

I've numerous articles on stackoverflow and others and I just can't see what I'm doing wrong? Anyone got any ideas?

谢谢.

推荐答案

问题已解决!!!

我的代码一直都正确,但是XAML却不正确!

My code was right all along but the XAML wasn't!

我猜陡峭而痛苦的学习曲线!无论如何,在找到有关stackoverflow的文章后,我找到了解决方案,该文章基本上向我表明,我编写xaml的方式不合适.

Steep and painful learning curve I guess! Anyway, I found a resolution after finding an article on stackoverflow which basically showed me that the way I wrote the xaml was just not appropriate.

说实话,我不明白为什么这不能按定义的方式工作,但总之,我必须使用HeaderTemplate和ItemTemplate才能在绑定到ViewModel时正确显示数据!

I'll be honest, I don't understand why this doesn't work the way it was defined but in short, I have to use HeaderTemplate and ItemTemplate in order to display the data correctly when binded to a ViewModel!

这里是帖子:数据绑定数据透视表未在Windows Phone 8中加载第一个PivotItem

这篇关于使用Observable Collection MVVM绑定透视图控件(Windows Phone 8)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆