免責聲明:本文章由fengyun1989創作,采用知識共享署名-非商業性使用-相同方式共享 2.5 中國大陸許可協議進行許可。
首先,打開VS2012,然后新建一個工程,命名為TimeTable。
點擊確定后,看到編譯器如下地方:
現在空的工程也可以運行,選擇Simulator就是模擬器運行,選擇本地計算機就是直接在本機運行。現在就可以運行看看,就是黑屏。
在本機運行的話,如果想退出程序,可以把光標放到左上角,等待出現桌面縮略圖就點擊,這樣就能退出了。
數據綁定
細想下這個工程,首先要做的是要把課程的數據顯示出來,那么,就要用到數據綁定了。熟悉wp7和silverlight開發的朋友,接下來你就會發現,在win8(XAML+c#)開發當中,數據綁定是一樣的。
首先,我們修改下我們的工程,新建一個命名為Resources.然后在 文件夾右鍵--添加--新建項,選取資源字典。命名為:MyDictionary.xaml。添加一行畫刷來作為背景。並且修改代碼如下:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:TimeTable.Resources"> <SolidColorBrush Color="#3E790A" x:Key="AppBackgroundColor"/> </ResourceDictionary>
現在打開App.xaml。添加對MyDicitonary.xaml的聲明。修改如下:
<ResourceDictionary.MergedDictionaries> <!-- Styles that define common aspects of the platform look and feel Required by Visual Studio project and item templates --> <ResourceDictionary Source="Common/StandardStyles.xaml"/> <ResourceDictionary Source="Resources/MyDictionary.xaml"/> </ResourceDictionary.MergedDictionaries>
現在修改MainPage.xaml的grid的背景。
<Grid Background="{StaticResource AppBackgroundColor}">
現在,就能看到背景色變為了深綠色。接下來就進行數據定義吧。我們的數據類都繼承INotifyPropertyChanged接口,以便數據更新的時候能夠自己通知控件更新。添加一個Data的文件夾。然后新建添加三個類,分別是ViewModel.cs,WeekdayItem.cs,ScheduleItem.cs .類圖如下:
代碼如下:
class ViewModel : INotifyPropertyChanged { private ObservableCollection<WeekdayItem> weekdayList; public ObservableCollection<WeekdayItem> WeekdayList { get { return weekdayList; } } private int selectedItemIndex; public int SelectedItemIndex { get { return selectedItemIndex; } set { selectedItemIndex = value; NotifyPropertyChanged("SelectedItemIndex"); } } public ViewModel() { weekdayList = new ObservableCollection<WeekdayItem>(); selectedItemIndex = -1; } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(string propName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propName)); } } }
class WeekdayItem : INotifyPropertyChanged { private ObservableCollection<ScheduleItem> scheduleList; private int scheduleSelected; public int ScheduleSelected { get { return scheduleSelected; } set { scheduleSelected = value; NotifyPropertyChanged("ScheduleSelected"); } } public ObservableCollection<ScheduleItem> ScheduleList { get { return scheduleList; } } public WeekdayItem() { scheduleList = new ObservableCollection<ScheduleItem>(); weekday = "Monday"; } private string weekday; public string Weekday { get { return weekday; } set { weekday = value; NotifyPropertyChanged("WeekDay"); } } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(string propName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propName)); } } }
class ScheduleItem : INotifyPropertyChanged { private string lessonName; public string LessonName { get { return lessonName; } set { lessonName = value; NotifyPropertyChanged("LessonName"); } } private string startTime; public string StartTime { get { return startTime; } set { startTime = value; NotifyPropertyChanged("StartTme"); } } private string endTime; public string EndTime { get { return endTime; } set { endTime = value; NotifyPropertyChanged("EndTime"); } } private string classRoom; public string ClassRoom { get { return classRoom; } set { classRoom = value; NotifyPropertyChanged("ClassRoom"); } } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(string propName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propName)); } } }
上面的代碼已經很清楚了。就不多說了。
下面進行數據綁定。首先,在MyDictionary.xaml的SolidColorBrush的下面添加下面一段代碼:
<Style x:Key="WeekdayListStyle" TargetType="TextBlock" BasedOn="{Binding BasicTextStyle}" > <Setter Property="FontSize" Value="45"/> <Setter Property="FontWeight" Value="Light"/> <Setter Property="Margin" Value="10,0"/> <Setter Property="VerticalAlignment" Value="Center"/> </Style> <DataTemplate x:Key="WeekdayListItemTemplate"> <TextBlock Text="{Binding Weekday}" Style="{StaticResource WeekdayListStyle}"/> </DataTemplate>
上面定義了一個數據模板,BasicTextStyle定義在Common/StandardStyles.xaml里面,這個文件里面定義了很多style。
下面修改MainPage的Grid。
<Grid Background="{StaticResource AppBackgroundColor}"> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <StackPanel Grid.RowSpan="2"> <TextBlock x:Name="WeekdayListTitle" Style="{StaticResource HeaderTextStyle}" Margin="10" Text="Weekday List"/> <ListView x:Name="weekdayList" Grid.RowSpan="2" ItemsSource="{Binding WeekdayList}" ItemTemplate="{StaticResource WeekdayListItemTemplate}" > </ListView> </StackPanel> <StackPanel Orientation="Vertical" Grid.Column="1" Grid.RowSpan="2"> <TextBlock Style="{StaticResource HeaderTextStyle}" Margin="10" x:Name="ItemDetailTitle" Text="Schedule Detail"/> <Frame x:Name="ItemDetailFrame"/> </StackPanel> </Grid>
上面定義的style除了自己定義的,基本都是在Common/StandardStyles.xaml里面。熟悉數據綁定的能在上面的代碼看到熟悉的代碼影吧。綁定了ListView的ItemsSource和ItemTemplate。下面的Frame標簽以后再講。
然后修改后台的構造函數和添加一個函數來往viewModel添加數據。
ViewModel viewModel; public MainPage() { viewModel = new ViewModel(); addData(); this.DataContext = viewModel; this.InitializeComponent(); } /// <summary> /// 往viewModel添加數據 /// </summary> private void addData() { WeekdayItem monday = new WeekdayItem(); monday.ScheduleList.Add(new ScheduleItem { ClassRoom = "B-215", StartTime = "8:30", EndTime = "10:00", LessonName = "Math" }); monday.ScheduleList.Add(new ScheduleItem { ClassRoom = "B-216", StartTime = "10:30", EndTime = "12:00", LessonName = "Physic" }); monday.ScheduleList.Add(new ScheduleItem { ClassRoom = "E-303", StartTime = "14:30", EndTime = "16:00", LessonName = "Computer" }); monday.Weekday = "星期一"; viewModel.WeekdayList.Add(monday); WeekdayItem tuesday = new WeekdayItem(); tuesday.Weekday = "星期二"; tuesday.ScheduleList.Add(new ScheduleItem { ClassRoom = "B-215", StartTime = "8:30", EndTime = "10:00", LessonName = "Math" }); tuesday.ScheduleList.Add(new ScheduleItem { ClassRoom = "B-216", StartTime = "10:30", EndTime = "12:00", LessonName = "Physic" }); tuesday.ScheduleList.Add(new ScheduleItem { ClassRoom = "E-303", StartTime = "14:30", EndTime = "16:00", LessonName = "English" }); viewModel.WeekdayList.Add(tuesday); WeekdayItem wednesday = new WeekdayItem(); wednesday.Weekday = "星期三"; wednesday.ScheduleList.Add(new ScheduleItem { ClassRoom = "B-215", StartTime = "8:30", EndTime = "10:00", LessonName = "數學" }); wednesday.ScheduleList.Add(new ScheduleItem { ClassRoom = "B-216", StartTime = "10:30", EndTime = "12:00", LessonName = "Physic" }); wednesday.ScheduleList.Add(new ScheduleItem { ClassRoom = "E-303", StartTime = "14:30", EndTime = "16:00", LessonName = "English" }); viewModel.WeekdayList.Add(wednesday); WeekdayItem thursday = new WeekdayItem(); thursday.Weekday = "星期四"; thursday.ScheduleList.Add(new ScheduleItem { ClassRoom = "B-215", StartTime = "8:30", EndTime = "10:00", LessonName = "數學" }); thursday.ScheduleList.Add(new ScheduleItem { ClassRoom = "B-216", StartTime = "10:30", EndTime = "12:00", LessonName = "Physic" }); thursday.ScheduleList.Add(new ScheduleItem { ClassRoom = "E-303", StartTime = "14:30", EndTime = "16:00", LessonName = "English" }); viewModel.WeekdayList.Add(thursday); WeekdayItem friday = new WeekdayItem(); friday.Weekday = "星期五"; friday.ScheduleList.Add(new ScheduleItem { ClassRoom = "B-215", StartTime = "8:30", EndTime = "10:00", LessonName = "數學" }); friday.ScheduleList.Add(new ScheduleItem { ClassRoom = "B-216", StartTime = "10:30", EndTime = "12:00", LessonName = "Physic" }); friday.ScheduleList.Add(new ScheduleItem { ClassRoom = "E-303", StartTime = "14:30", EndTime = "16:00", LessonName = "English" }); viewModel.WeekdayList.Add(friday); }
在構造函數,我們指定了當前頁面的信息源DataContext為當前聲明的viewModel。現在編譯運行,就能看到運行結果如下:
下面我們要使用frame這個標簽了。其實,每個頁面都有這個Frame這個屬性,這個Frame直接控制了導航,導航在Wp7里是用navigationService來完成的。不過可能是由於平板的屏幕大,所以用這個Frame標簽就可以做到局部導航。使之可以所有操作都在一個頁面完成。不過,如果開發者不實現導航返回按鈕,win8平板就中間一個window鍵。如果能夠返回上一層頁面?至少我還沒發現什么操作可以實現。
下面先給ListView添加一個SelectionChanged事件。當選項改變時觸發。
private void weekdayList_SelectionChanged_1(object sender, SelectionChangedEventArgs e) { viewModel.SelectedItemIndex = weekdayList.SelectedIndex; }
只做了一件事,就是修改了viewModel的SelectedItemIndex的值。那么我們要注冊一個PropertyChanged事件,監聽當這個SelectedItemIndex改變的時候做相應的工作。
在Mainpage的構造函數最后添加:
viewModel.PropertyChanged += (sender, args) => { if (args.PropertyName == "SelectedItemIndex") { if (viewModel.SelectedItemIndex == -1) { ItemDetailFrame.Navigate(typeof(NoItemSelected)); } else { ItemDetailFrame.Navigate(typeof(ItemDetail), viewModel); } } };
上面我們監聽了SelectedItemIndex。當改變的時候使ItemDetailFrame這個Frame導航到不同的頁面。這個navigate方法,由VS2012的智能提示就知道,可以帶參數,也可以不帶參數。
下面我們新建一個文件夾Pages。然后添加一個空頁面NoItemSelected.xaml。修改代碼如下:
<Grid Background="{StaticResource AppBackgroundColor}"> <TextBlock Style="{StaticResource HeaderTextStyle}" FontSize="30" Text="No Item Selected"/> </Grid>
然后再添加一個空白頁ItemDetail.xaml到Pages文件夾。修改代碼如下:
<Grid Background="{StaticResource AppBackgroundColor}"> <ListView x:Name="ScheduleList" ItemsSource="{Binding ScheduleList}" IsHoldingEnabled="True" ItemTemplate="{StaticResource ScheduleListItemTemplate}"/> </Grid>
然后修改ItemDetail頁面的OnNavigateTo方法並添加一個變量。
ViewModel viewModel;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
viewModel = e.Parameter as ViewModel;
this.DataContext = viewModel.WeekdayList[viewModel.SelectedItemIndex];
viewModel.PropertyChanged += (sender, args) =>
{
if (viewModel.SelectedItemIndex == -1)
{
this.DataContext = null;
}
else
this.DataContext = viewModel.WeekdayList[viewModel.SelectedItemIndex];
};
}
上面OnNavigateTo方法,在頁面進入的時候,就獲取頁面傳遞過來的ViewModel這個數據。然后指定當前選擇的Weekday為數據源。
上面我們還沒定義ItemDetail頁面ListView的數據模版。在MyDictionary.xaml添加如下模版:
<DataTemplate x:Key="ScheduleListItemTemplate"> <StackPanel Orientation="Vertical"> <TextBlock Text="{Binding LessonName}" FontSize="30"/> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding StartTime}" FontSize="18"/> <TextBlock Text="-" FontSize="18"/> <TextBlock Text="{Binding EndTime}" FontSize="18"/> </StackPanel> <TextBlock Text="{Binding ClassRoom}" FontSize="30"/> </StackPanel> </DataTemplate>
這樣,編譯運行,就能看到選擇左邊的WeekdayList就能改變右邊的ItemDetail部分了。到此,數據綁定部分基本就這樣吧。還有部分彈出窗口的數據綁定到后面再說。
繼續學習:<win8>(三)實例講解win8(XAML+C#)開發--------課程表:彈出菜單ContextMenu和彈窗Flyout
本次工程下載:http://dl.dbank.com/c0eh4b1z85