(三)實例講解win8(XAML+C#)開發--------課程表:彈出菜單ContextMenu和彈窗Flyout

 免責聲明:本文章由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)





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章