我是WP8的新手& MVVM。我创建了wp8应用程序,它在用户登录后请求各种数据位。我只是无法让我的pivot标题动态创建,我不知道是否因为我在绑定中做了某些事情, INotifyPropertyChanged,两者或别的东西!使用Observable Collection MVVM绑定枢轴控件(windows phone 8)
这是我迄今所做的:
我得在App.cs定义的全局MainViewModel将存储在用户登录时都返回的数据。
一旦登录成功并且数据已被加载到MainViewModel中,我将其重定向到包含数据透视控件的测试页面,并试图动态创建数据透视项目。
这是我的测试页的xaml,即MainPivotPage.xaml和我的MainPivotViewModel被初始化,因为它被定义为本地资源,并且设置为数据透视控件的数据上下文,我不知道我是否在做这个权利,但我将“名称”属性分配给PivotItem的Header,这是存储在我的可观察集合Pivots中的对象。属性Name是我在一个名为Pivot的类中包含PivotId和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,我的支点观察集合设置为存储在我的MainViewModel同样观察到的集合包含在登录所有返回的数据。正如你可以看到我把它分配给属性,而不是内部变量,以确保它会触发INotifyPropertyChanged的(嗯...,我认为)
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事件时都这样做。
这是我的基本视点代码:
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));
}
}
}
我的透视类看起来是这样的:
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类需要的,但我尝试了不同的场景,现在就把它留下。
我不知道我在做什么错,但无论我尝试什么,我都无法使“名称”属性显示为标题的文本。我很确定MainPivotViewModel被初始化时,它被分配为本地资源,因为它正确地调用我的构造函数,然后初始化我的可观察集合,但这就像它一样。
但它绝对没有显示!
我注意到的另一件事是,当我在BaseViewModel类的OnPropertyChanged方法的“Set”中放置断点时,eventHandler始终为空,无论我认为应该如何,但我可以'看看我做错了什么。
我有很多关于stackoverflow和其他人的文章,我只是不明白我做错了什么?任何人有任何想法?
谢谢。
你是否在任何地方设置了你的页面的'DataContext'? – 2013-03-27 07:12:26
嗨,是的,它设置在上面的xaml中。这只是不可见,但如果你滚动,你会看到它被设置。 – Thierry 2013-03-27 13:00:22
你有一个'Pivot'的ObservableCollection。这些是你自己的班级吗?如果是这样,他们看起来像什么? – 2013-03-27 15:00:18