我是新手WP8和MVVM。我创建了一个WP8应用程序,一旦用户登录,就会请求各种数据。我无法动态创建我的Pivot标题,我不知道这是因为我在绑定中做了什么,INotifyPropertyChanged,两者都还是其他原因!
到目前为止,我已经完成了以下工作:
我定义了一个全局MainViewModel,在App.cs中存储所有在登录时返回的数据。
一旦登录成功并将数据加载到MainViewModel中,我将其重定向到一个测试页面,其中包含一个Pivot控件,我正在尝试动态创建Pivot项目。
这是我的测试页面即MainPivotPage.xaml的xaml,我的MainPivotViewModel被初始化,因为它被定义为本地资源,并设置为Pivot控件的数据上下文,我不知道我是否做对了,但我将“Name”属性分配给PivotItem的Header,这是存储在我的可观察集合Pivots中的对象。 Name属性是我在称为Pivot的类中拥有的2个属性之一,该类包含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被创建时,我将Pivots可观察集合设置为存储在我的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);
}
}
}
我使用Base类中包含的SetProperty函数,它用于生成INotifyPropertyChanged事件,并且允许我在每次需要INotifyPropertyChanged事件时不必设置属性名称。
这是我的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类如下所示:
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类是否需要这个,但我试过不同的场景,现在还留着它。
我不知道我哪里做错了,但无论我尝试什么,都无法将“Name”属性显示为标题文本。我很确定MainPivotViewModel在被分配为本地资源时已经初始化了,因为它正确地调用了我的构造函数,而我的可观察集合也被初始化了,但就是这样,它什么也没有显示。
另一件我注意到的事情是,当我在BaseViewModel类的OnPropertyChanged方法的“Set”中放置断点时,无论如何eventHandler始终为空,这应该不是我想要的情况,但我看不出我做错了什么。
我在stackoverflow和其他地方阅读了无数篇文章,但就是找不出我做错了什么。有人有什么想法吗?
谢谢。
DataContext
吗? - Paul AnnettsPivot
的ObservableCollection
。这些是你自己的类吗?如果是,它们长什么样子? - Matt Lacey