免責聲明:本文章由fengyun1989創作,採用知識共享署名-非商業性使用-相同方式共享 2.5 中國大陸許可協議進行許可。
友情提示下:win8下,輸入法切換是window鍵+空格鍵。
下面我們來做的是一個彈窗來修改課程表裏面的數據。那麼我們用一個彈窗來實現數據的修改。那麼用什麼方式控制彈窗呢,用一個AppBar的按鈕?我覺得還是在頁面點擊彈出比較好,我想用listView的某個事件來實現彈窗,但是我對win8裏面的ListView的事件不太熟悉,查文檔?我比較懶,懶得查文檔也有兩種方式,一種用智能提示,一種用屬性頁面的事件頁。
從智能提示看到,可以選擇的事件挺多的,我就選擇DoubleTap.那麼在ItemDetail頁面添加一個DoubleTap事件:
<ListView x:Name="ScheduleList" ItemsSource="{Binding ScheduleList}"
DoubleTapped="ScheduleList_DoubleTapped_1"
ItemTemplate="{StaticResource ScheduleListItemTemplate}" />
那麼我們在DoubleTap事件中實現彈出菜單。這裏就先給出微軟官方的ContextMenu的例子:http://code.msdn.microsoft.com/windowsapps/Context-menu-sample-40840351
ContextMenu有兩種,一種是普通就彈出菜單,一種是選擇文本後的彈出菜單。這裏就用第一種,後一種是可以在選擇文本後彈出菜單顯示覆制,粘貼等。後一種可以在微軟給出的例子的Scenario2頁面看到。
修改DoubleTap事件如下:
private async void ScheduleList_DoubleTapped_1(object sender, DoubleTappedRoutedEventArgs e)
{
if (ScheduleList.SelectedIndex != -1)
{
var menu = new PopupMenu();
menu.Commands.Add(new UICommand("Edit", (command) =>
{
}));
menu.Commands.Add(new UICommand("Delete", (command) =>
{
}));
await menu.ShowAsync(e.GetPosition(null));
}
}
注意,這裏的方法要修改爲異步的,async和await這兩個配合,await這個關鍵字,在win8纔有,從字面文字就知道,就是等待後面的完成。用了await方法修飾,後面跟的要是異步的方法,整個方法也要用async修飾成異步的方法。關於await,推薦看:深入探究 WinRT 和 await
現在運行,在ListView上雙擊,就可以看到彈窗了。
接下來,我們做一個彈窗來修改數據。那麼,用什麼樣的形式彈窗呢,在Wp7,我們可以用Canvas自定義彈窗,也有不少的第三方插件可以做到。當然,這裏我們也可由用Canvas來自定義彈窗,不過這裏我不打算這麼做,我打算用win8有的一個彈窗Popup來實現。那麼現在新建添加一個用戶控件到Pages文件夾命名爲EditItemFlyout.xaml。
去除原來的Grid修改代碼如下:
<Popup x:Name="EditItemPopup" IsLightDismissEnabled="True" Width="435" Height="500">
<StackPanel Background="Black">
<Border Background="#85c54C" BorderThickness="4">
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Text="LessonName:" Grid.Column="0" Grid.Row="0" FontSize="24"/>
<TextBox x:Name="Lessonname" Width="200" Height="40"
Grid.Column="1" Grid.Row="0" Text="{Binding LessonName}" FontSize="24"/>
<TextBlock Text="ClassRoom:" Grid.Column="0" Grid.Row="1" FontSize="24"/>
<TextBox x:Name="Classroom" Grid.Column="1" Grid.Row="1" Width="200" Height="40"
Text="{Binding ClassRoom}" FontSize="24"/>
<TextBlock Text="StartTime:" Grid.Column="0" Grid.Row="2" FontSize="24" />
<TextBox x:Name="Starttime" Grid.Column="1" Grid.Row="2" Width="200" Height="40"
Text="{Binding StartTime}" FontSize="24"/>
<TextBlock Text="EndTime:" Grid.Column="0" Grid.Row="3" FontSize="24"/>
<TextBox x:Name="Endtime" Grid.Column="1" Grid.Row="3" Width="200" Height="40"
Text="{Binding EndTime}" FontSize="24"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Grid.ColumnSpan="2" Grid.Row="4">
<Button Content="OK" Margin="10,10" Click="Button_Click_1"/>
<Button Content="Cancel" Margin="50,10" Click="Button_Click_2"/>
</StackPanel>
</Grid>
</Border>
</StackPanel>
</Popup>
修改後臺代碼如下:
public void Show()
{
EditItemPopup.IsOpen = true;
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
var schedule = this.DataContext as ScheduleItem;
schedule.LessonName = Lessonname.Text;
schedule.ClassRoom = Classroom.Text;
schedule.StartTime = Starttime.Text;
schedule.EndTime = Endtime.Text;
EditItemPopup.IsOpen = false;
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
EditItemPopup.IsOpen = false;
}
這裏的前臺做了數據的綁定。後臺Button1確定數據更新。
另外在這裏多說下,我現在這個編譯器,每次在這個用戶控件這個頁面,鼠標在設計器多晃幾下,編譯器就有種掛了的感覺,經過研究,其實是設計器的預覽模塊惹的禍。如果感覺如此,就打開任務管理器。
就會看到如下:
這裏圈出來的就是設計器部分,佔用率很高,直接把圈出來的這個進程這個終結了就好了。不曉得這個是我機子的原因還是編譯器的問題,另外,Vs2012的智能提示不太好,在前臺設置的Name屬性,在後臺智能提示不行,還得生成下才行。
下面修改ItemDetail頁面,在Listview後面添加這麼一些代碼:
<local:EditItemFlyout x:Name="EditFlyout" VerticalAlignment="Top" HorizontalAlignment="Left"
Margin="300,200,0,0"/>
並且修改ListView的DoubleTap事件:
private async void ScheduleList_DoubleTapped_1(object sender, DoubleTappedRoutedEventArgs e)
{
if (ScheduleList.SelectedIndex != -1)
{
var menu = new PopupMenu();
menu.Commands.Add(new UICommand("Edit", (command) =>
{
EditFlyout.DataContext = ((WeekdayItem)this.DataContext).ScheduleList[ScheduleList.SelectedIndex];
EditFlyout.Show();
}));
menu.Commands.Add(new UICommand("Delete", (command) =>
{
((WeekdayItem)this.DataContext).ScheduleList.RemoveAt(ScheduleList.SelectedIndex);
}));
await menu.ShowAsync(e.GetPosition(null));
}
}
上面代碼做了就是顯示Flyout和數據的綁定,刪除的時候就對數據修改刪除就好了。現在編譯運行,就能看到彈窗,修改或者刪除都能實現了。
下面做Weekdaylist的彈出菜單來作爲添加刪除等。那麼也用DoubleTap事件吧。
WeekdayList的doubleTap事件如下:
private async void weekdayList_DoubleTapped_1(object sender, DoubleTappedRoutedEventArgs e)
{
var menu = new PopupMenu();
menu.Commands.Add(new UICommand("Add Weekday", (command) =>
{
ItemDetailFrame.Navigate(typeof(AddWeekday), viewModel);
}));
menu.Commands.Add(new UICommand("Add Schedule", (command) =>
{
if (weekdayList.SelectedIndex != -1)
{
ItemDetailFrame.Navigate(typeof(AddSchedule), viewModel);
}
}));
menu.Commands.Add(new UICommand("Delete this Item", (command) =>
{
if (weekdayList.SelectedIndex != -1)
{
viewModel.WeekdayList.RemoveAt(weekdayList.SelectedIndex);
}
}));
await menu.ShowAsync(e.GetPosition(null));
}
addWeekday,Addschedule是兩個頁面,ItemDetail這個Frame導航到這兩個頁面,並且傳入viewModel這個數據。來實現數據的更新。
現在新建兩個頁面AddSchedule,AddWeekday到Pages文件夾,代碼如下:
AddSchedule前臺如下:
<Grid Background="{StaticResource AppBackgroundColor}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="LessonName:" FontSize="24" HorizontalAlignment="Center" VerticalAlignment="Top"
Grid.Column="0" Grid.Row="0"/>
<TextBox x:Name="Lessonname" Width="200" Height="40" HorizontalAlignment="Left" VerticalAlignment="Top"
Grid.Column="1" Grid.Row="0"/>
<TextBlock Text="ClassRoom:" Grid.Column="0" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Top"
FontSize="24"/>
<TextBox x:Name="Classroom" Grid.Column="1" Grid.Row="1" Width="200" Height="40"
HorizontalAlignment="Left" VerticalAlignment="Top"/>
<TextBlock Text="StartTime:" Grid.Column="0" Grid.Row="2" HorizontalAlignment="Center" VerticalAlignment="Top"
FontSize="24"/>
<TextBox x:Name="Starttime" Grid.Column="1" Grid.Row="2" HorizontalAlignment="Left" VerticalAlignment="Top"
Width="200" Height="40"/>
<TextBlock Text="EndTime:" Grid.Column="0" Grid.Row="3" HorizontalAlignment="Center" VerticalAlignment="Top"
FontSize="24"/>
<TextBox x:Name="Endtime" Grid.Column="1" Grid.Row="3" HorizontalAlignment="Left" VerticalAlignment="Top"
Width="200" Height="40"/>
<Button x:Name="Addschedule" Content="Add" Width="150" Height="40" Click="Addschedule_Click_1"
Grid.Column="0" Grid.Row="4" VerticalAlignment="Top" HorizontalAlignment="Center"/>
<Button x:Name="Cancel" Content="Cancel" Width="150" Height="40" HorizontalAlignment="Left"
VerticalAlignment="Top" Click="Cancel_Click_1" Grid.Column="1" Grid.Row="4"/>
</Grid>
上面定義了數據的佈局。
後臺代碼:(添加一個聲明和在onnavigateto的時候獲取數據源,在點擊添加和取消的時候並完成頁面導航)
private ViewModel viewModel;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
viewModel = e.Parameter as ViewModel;
}
private void Addschedule_Click_1(object sender, RoutedEventArgs e)
{
if (Lessonname.Text.Length <= 0 || Classroom.Text.Length <= 0 || Starttime.Text.Length <= 0 || Endtime.Text.Length <= 0)
{
return;
}
WeekdayItem item = viewModel.WeekdayList[viewModel.SelectedItemIndex];
ScheduleItem scheduleItem = new ScheduleItem();
scheduleItem.LessonName = Lessonname.Text;
scheduleItem.ClassRoom = Classroom.Text;
scheduleItem.StartTime = Starttime.Text;
scheduleItem.EndTime = Endtime.Text;
item.ScheduleList.Add(scheduleItem);
if (viewModel.SelectedItemIndex == -1)
{
this.Frame.Navigate(typeof(NoItemSelected));
}
else
this.Frame.Navigate(typeof(ItemDetail), viewModel);
}
private void Cancel_Click_1(object sender, RoutedEventArgs e)
{
if (viewModel.SelectedItemIndex == -1)
{
this.Frame.Navigate(typeof(NoItemSelected));
}
else
this.Frame.Navigate(typeof(ItemDetail), viewModel);
}
上面用了另一個導航方式,調用了頁面的Frame屬性來完成導航,另一個頁面也是一樣的方法,在此附上代碼,就不多加解釋了。
AddWeekday前臺:
<Grid Background="{StaticResource AppBackgroundColor}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="WeekDayName:" FontSize="24" Grid.Column="0" Grid.Row="0"/>
<TextBox x:Name="WeekdayName" Width="200" Height="40" Grid.Column="1" Grid.Row="0" Margin="0,0"
HorizontalAlignment="Left" VerticalAlignment="Top"/>
<Button x:Name="Addweekday" Content="Add" Grid.Column="0" Grid.Row="1" Click="AddWeekdayClick"
HorizontalAlignment="Left" VerticalAlignment="Top" Width="200"/>
<Button x:Name="Cancel" Content="Cancel" Grid.Column="1" Grid.Row="1" Click="CancelClick"
HorizontalAlignment="Left" VerticalAlignment="Top" Width="200"/>
</Grid>
AddWeekday後臺:
private ViewModel viewModel;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
viewModel = e.Parameter as ViewModel;
}
private void AddWeekdayClick(object sender, RoutedEventArgs e)
{
if (WeekdayName.Text.Length <= 0)
{
return;
}
WeekdayItem item = new WeekdayItem();
item.Weekday = WeekdayName.Text;
viewModel.WeekdayList.Add(item);
if (viewModel.SelectedItemIndex == -1)
{
this.Frame.Navigate(typeof(NoItemSelected));
}
else
this.Frame.Navigate(typeof(ItemDetail), viewModel);
}
private void CancelClick(object sender, RoutedEventArgs e)
{
if (viewModel.SelectedItemIndex == -1)
{
this.Frame.Navigate(typeof(NoItemSelected));
}
else
this.Frame.Navigate(typeof(ItemDetail), viewModel);
}
到這裏,編譯運行,就能看到,在左邊listView雙擊添加,刪除了。
在這裏,提醒大家在用模擬器的時候儘量用模擬手勢的選項,在右邊工具欄可以選擇。這樣,就能更好模擬手指了。選項如下圖紅色方框中。
本次工程下載:http://dl.dbank.com/c0jrblh51s
繼續學習:<win8>(四)實例講解win8(XAML+C#)開發--------課程表:Snapped模式和動態磁貼,徽章(badge)