亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

如何將GridViewEX升級到UWP(UniversalWindowsPlatform)平臺

2019-11-14 13:50:59
字體:
來源:轉載
供稿:網友

引言

 

上一篇文章中,我們主要講解了如何在保證GridView控件的用戶體驗基礎上,擴展GridView生成GridViewEx控件,增加動態添加新分組功能等,本文在上文的基礎上,介紹如何在Windows10中使用GridViewEx,開發UWP應用。

extended GridView with grouping, variable sized items and drag and drop support

 

Demo 下載:

GridViewLiveTiles.zip

 GridViewEx.zip

 GridViewDemo.zip

開發UWP應用程序

開發UWP應用程序最好是從創建empty項目開始,重用已開發的一些模塊,這樣可以提高開發效率。

本文為了創建UWP 應用程序,首先創建一些通用類如下,詳細代碼見附件:

  • Common/VisibilityConverter.cs
  • Common/LayoutAwarePage.cs
  • Common/SuspensionManager.cs

DataModel 和Sample 文件夾下的所有文件都可以重用。

修改布局和導航

VisibilityConverter 和 SuspensionsManager暫時不需要修改,可直接在UWP中使用。主要修改布局和導航邏輯文件。

由于微軟支持的設備種類越來越多,導致applicationViewState不再適用。UWP平臺提供了其他的解決方法如AdaptiveTriggers,內置了自適應布局。因此創建UWP應用程序,首先需要刪除所有ApplicationViewStates的代碼。可能會導致使用LayoutAwarePage的部分會報錯。因此我們需要做一些兼容性的改變。

無論是WinRT還是UWP應用,都會使用返回鍵導航。桌面WinRTx應用會在Xaml文件添加返回按鈕。但是在UWP應用中,非常靈活,桌面應用可以在標題欄中添加返回按鈕,在移動設備中不僅能使用標題欄中的返回鍵,也可以使用物理返回鍵實現導航功能。UWP的方法比較通用,且不需要編寫自定義的Xaml文件。因此只需要開發一個基類,應用到不同的Xaml 頁面中就可以實現輕松實現導航功能,不需要重復編寫代碼。修改后的LayoutAwarePage 類:

   1:  PRotected override void OnNavigatedTo(NavigationEventArgs e)
   2:  {
   3:      // subscribe on Back button event
   4:      if (IsWindowsPhoneDevice())
   5:      {
   6:          // use hardware button
   7:          Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;
   8:      }
   9:      else
  10:      {
  11:          // enable/disable window back button depending on navigation state
  12:          var currentView = SystemNavigationManager.GetForCurrentView();
  13:          currentView.AppViewBackButtonVisibility = this.Frame != null && this.Frame.CanGoBack ?
  14:              AppViewBackButtonVisibility.Visible : AppViewBackButtonVisibility.Collapsed;
  15:          currentView.BackRequested += backButton_Tapped;
  16:      }
  17:      ...
  18:  protected override void OnNavigatedFrom(NavigationEventArgs e)
  19:  {
  20:      // unsubscribe from Back button event
  21:      if (IsWindowsPhoneDevice())
  22:      {
  23:          Windows.Phone.UI.Input.HardwareButtons.BackPressed -= HardwareButtons_BackPressed;
  24:      }
  25:      else
  26:      {
  27:          // unsubscribe from window back button
  28:          var currentView = SystemNavigationManager.GetForCurrentView();
  29:          currentView.BackRequested -= backButton_Tapped;
  30:      }
  31:      ...
  32:  // handle Back button events
  33:  private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
  34:  {
  35:      if (this.Frame != null && this.Frame.CanGoBack)
  36:      {
  37:          e.Handled = true;
  38:          this.Frame.GoBack();
  39:      }
  40:  }
  41:  private void backButton_Tapped(object sender, BackRequestedEventArgs e)
  42:  {
  43:      this.GoBack(this, new RoutedEventArgs());
  44:  }

 

因為需要使用物理返回鍵,我們需要在程序中添加引用文件“Windows Mobile Extensions for the UWP”。

現在由LayoutAwarePage派生而來的所有頁面都可直接使用,無需在多個文件中添加引用。

LayoutAwarePage 類最后添加設備查詢的靜態方法,來檢測運行時設備。

   1:  public static bool IsWindowsPhoneDevice()
   2:  {
   3:      if (Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons"))
   4:      {
   5:          return true;
   6:      }    
   7:      return false;
   8:  }

 

其他平臺

1. 如果想保證應用程序在Windows10中具有與系統一致的界面風格和用戶體驗,可使用Windows 10 ThemeResources (主題資源)。

2. 微軟也在Windows10 發布中升級了GridView控件,相對于Windows 8 版本來說,最重要的改變是添加了用戶重定向檢測。

3. VariableSizedWrapGrid 面板也添加了重定向檢測功能。并且去掉了行和列自動展開的功能。下面是Windows8 版本的Xaml文件,在Windows10 中已經無法使用。

   1:  <GridView  Grid.Row="1" Grid.Column="1" Margin="10" AllowDrop="True" CanReorderItems="True" CanDragItems="True" IsSwipeEnabled="True">
   2:                  <GridView.ItemsPanel>
   3:                      <ItemsPanelTemplate>
   4:                          <VariableSizedWrapGrid/>
   5:                      </ItemsPanelTemplate>
   6:                  </GridView.ItemsPanel>
   7:                  <Rectangle Height="100" Width="200" Fill="Blue" />
   8:                  <Rectangle Height="100" Width="100" Fill="Red" />
   9:                  <Rectangle Height="100" Width="100" Fill="Yellow" />
  10:                  <Rectangle Height="100" Width="100" Fill="Green" />

最好的解決方法就是將VariableSizedWrapGrid 與item的屬性綁定,并將值傳給自定義的GridView控件的ListViewItemPresenter 元素:

   1:  /// <summary>
   2:  /// This class sets VariableSizedWrapGrid.ColumnSpanProperty for GridViewItem controls,
   3:  /// so that every item can have different size in the VariableSizedWrapGrid.
   4:  /// Also it sets VerticalContentAlignment and HorizontalContentAlignment to Stretch.
   5:  /// </summary>
   6:  public class GridViewTiled : GridView
   7:  {
   8:      // set ColumnSpan according to the business logic (maybe some GridViewSamples.Samples.Item or group properties)
   9:      protected override void PrepareContainerForItemOverride(Windows.UI.Xaml.DependencyObject element, object item)
  10:      {
  11:          element.SetValue(ContentControl.HorizontalContentAlignmentProperty, HorizontalAlignment.Stretch);
  12:          element.SetValue(ContentControl.VerticalContentAlignmentProperty, VerticalAlignment.Stretch);
  13:          UIElement el = item as UIElement;
  14:          if (el != null)
  15:          {
  16:              int colSpan = Windows.UI.Xaml.Controls.VariableSizedWrapGrid.GetColumnSpan(el);
  17:              int rowSpan = Windows.UI.Xaml.Controls.VariableSizedWrapGrid.GetRowSpan(el);
  18:              if (rowSpan > 1)
  19:              {
  20:                  // only set it if it has non-defaul value
  21:                  element.SetValue(Windows.UI.Xaml.Controls.VariableSizedWrapGrid.RowSpanProperty, rowSpan);
  22:              }
  23:              if (colSpan > 1)
  24:              {
  25:                  // only set it if it has non-defaul value
  26:                  element.SetValue(Windows.UI.Xaml.Controls.VariableSizedWrapGrid.ColumnSpanProperty, colSpan);
  27:              }
  28:          }
  29:          base.PrepareContainerForItemOverride(element, item);
  30:      }
  31:  }

 

UWP中的XAML文件:

<controls:GridViewTiled Grid.Row="1" Grid.Column="1" Margin="10" AllowDrop="True" CanReorderItems="True" CanDragItems="True" >    <controls:GridViewTiled.ItemsPanel>        <ItemsPanelTemplate>            <VariableSizedWrapGrid ItemHeight="100" ItemWidth="100" Orientation="Horizontal"/>        </ItemsPanelTemplate>    </controls:GridViewTiled.ItemsPanel>    <Rectangle VariableSizedWrapGrid.ColumnSpan="2" VariableSizedWrapGrid.RowSpan="2" Fill="Blue" />    <Rectangle Fill="Red" />    <Rectangle Fill="Yellow" />    <Rectangle Fill="Green" />

新占位符(NewGroupPlaceholder)控件

WinRT版的GridViewEx控件使用了簡單border作為新分組的占位符,在拖拽項過程中外觀是靜態的,無法改變。為了使界面對用戶更加友好,并且將拖放的位置高亮, 因此我們新建了新的“NewGroupPlaceholder”控件,在拖拽過程中有簡單的狀態切換邏輯。

GridViewEx - NewGroupPlaceholder

代碼很簡單,見附件,系統提供的控件模板代碼如下:

   1:  <Style TargetType="local:NewGroupPlaceholder">
   2:      <Setter Property="Background" Value="Transparent" />
   3:      <Setter Property="Margin" Value="8" />
   4:      <Setter Property="Height" Value="32" />
   5:      <Setter Property="Template">
   6:          <Setter.Value>
   7:              <ControlTemplate TargetType="local:NewGroupPlaceholder">
   8:                  <Border x:Name="root" Background="{TemplateBinding Background}">
   9:                      <VisualStateManager.VisualStateGroups>
  10:                          <VisualStateGroup x:Name="DragStates">
  11:                              <VisualState x:Name="Normal"/>
  12:                              <VisualState x:Name="DragOver">
  13:                                  <Storyboard>
  14:                                      <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="dragOverElement"/>
  15:                                  </Storyboard>
  16:                              </VisualState>
  17:                          </VisualStateGroup>
  18:                      </VisualStateManager.VisualStateGroups>
  19:                      <Border x:Name="dragOverElement" Background="{ThemeResource SystemControlHighlightListAccentLowBrush}" Opacity="0"/>
  20:                  </Border>
  21:              </ControlTemplate>
  22:          </Setter.Value>
  23:      </Setter>
  24:  </Style>

修改GridViewEx 控件

接下來,我們將介紹如何修改GridViewEx控件,使得其可以適應UWP。

UWP平臺下運行GridViewEx大部分的功能與WinRT保持一致。只有OnDragOver中的DragEventArgs.AcceptedOperation 屬性需要重寫。顯然UWP 中的GridView 將所有非空項的該屬性都設置為None。因此,如果不重寫OnDragOver 方法,Drop 事件就不會被觸發。

代碼如下:

   1:  protected override void OnDragOver(DragEventArgs e)
   2:  {
   3:      int newIndex = GetDragOverIndex(e);
   4:      if (newIndex >= 0)
   5:      {
   6:          e.AcceptedOperation = Windows.ApplicationModel.DataTransfer.DataPackageOperation.Move;

運行代碼時編譯器會發出很多關于ItemContainerGenerator 方法的警告,調用ItemsControl 響應方法就可以處理Warning

VariableSizedWrapGrid存在很多限制,為了解決這些限制,在上述代碼中添加 PrepareContainerForItemOverride 方法。最后需要升級GridViewEx 控件自帶的樣式,使其支持設備重定向。

更加適應手持設備

在GridViewEx控件中添加新的PreparingContainerForItem 事件,該事件的參數即包含數據對象,也包含UI 容器,因此可根據需求設置UI屬性,代碼如下:

   1:  /// <summary>
   2:  /// Set column spans depending on group id.
   3:  /// </summary>
   4:  /// <param name="sender"></param>
   5:  /// <param name="e"></param>
   6:  private void gve_PreparingContainerForItem(object sender, GridViewEx.PreparingContainerForItemEventArgs e)
   7:  {
   8:      try
   9:      {
  10:          Item it = e.Item as Item;
  11:          if (it != null)
  12:          {
  13:              e.Element.SetValue(Windows.UI.Xaml.Controls.VariableSizedWrapGrid.ColumnSpanProperty, it.GroupId % 2 + 1);
  14:          }
  15:      }
  16:      catch
  17:      {
  18:          e.Element.SetValue(Windows.UI.Xaml.Controls.VariableSizedWrapGrid.ColumnSpanProperty, 1);
  19:      }
  20:  }

在多設備中具有良好用戶體驗

 為了適應多種設備,需要生成自適應布局。本文中主要通過修改內容項的尺寸來實現該功能。創建了Bound ,Unbound以及Grouped 示例文件,Grouped 顯示單個GridView控件,因此在移動端能夠修改Tile的尺寸及邊框。

Bound 和Unbound 示例是由2個GridView控件組成,小屏幕中顯的內容較多,無法顯示更多的細節性的內容,因此使用Pivot控件保證同一時間只顯示一個GridView控件,并支持GridView之間切換。

代碼如下:

   1:  public double TileSize
   2:  {
   3:      get { return (double)GetValue(TileSizeProperty); }
   4:      set { SetValue(TileSizeProperty, value); }
   5:  }
   6:  public static readonly DependencyProperty TileSizeProperty =
   7:      DependencyProperty.Register(nameof(TileSize), typeof(double), typeof(Customized), new PropertyMetadata(100));
   8:  public Customized()
   9:  {
  10:      if (IsWindowsPhoneDevice())
  11:      {
  12:          TileSize = 72;
  13:      }
  14:      this.InitializeComponent();
  15:  }

GridViewEx 和GridView 中綁定代碼如下:

   1:  <GroupStyle.Panel>
   2:      <ItemsPanelTemplate>
   3:          <VariableSizedWrapGrid ItemHeight="{Binding TileSize, ElementName=pageRoot}"
   4:                                 ItemWidth="{Binding TileSize, ElementName=pageRoot}"
   5:                                 Orientation="Horizontal" MaximumRowsOrColumns="10"/>
   6:      </ItemsPanelTemplate>
   7:  </GroupStyle.Panel>

 

總結

自定義GridViewEx控件擴展了GridView控件,豐富了功能,并新增適應UWP平臺App的開發。

示例圖片:

live tiles

 

原文鏈接:http://www.codeproject.com/Articles/1037059/How-to-Upgrade-Extended-GridView-from-WinRT-to-Uni


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产97在线|日韩| 亚洲精品国产精品国自产在线| 国产aⅴ夜夜欢一区二区三区| 国产一区二区三区直播精品电影| 国产精品你懂得| 亚洲欧洲日产国码av系列天堂| 日本午夜在线亚洲.国产| 国产精品一二三在线| 中文字幕久热精品视频在线| 国产成人精品视频| 日韩有码在线观看| 国内精品久久久久影院 日本资源| 欧美午夜精品久久久久久人妖| 成人福利网站在线观看11| 亚洲自拍偷拍第一页| 亚洲综合中文字幕68页| 日韩av日韩在线观看| 久久成人精品视频| 正在播放亚洲1区| 97av视频在线| 午夜欧美大片免费观看| 国产精品国产三级国产专播精品人| 亚洲人线精品午夜| 在线精品国产成人综合| 欧美成人在线免费视频| 68精品国产免费久久久久久婷婷| 国产精品久久久久久网站| 日韩欧美国产一区二区| 久久久久久亚洲精品中文字幕| 久久久成人的性感天堂| 国产精品日韩在线一区| 国产综合视频在线观看| 91精品久久久久久久久中文字幕| 亚洲精品在线观看www| 日韩欧美在线国产| 国产精品福利无圣光在线一区| 成人久久精品视频| 久久国产加勒比精品无码| 日韩人在线观看| 欧美日韩国产区| 日韩欧美亚洲一二三区| 久久中文字幕一区| 久久91亚洲人成电影网站| 欧美日韩国产在线| 亚洲人午夜精品免费| 亚洲精品91美女久久久久久久| 欧美老肥婆性猛交视频| 91av视频在线免费观看| 成人午夜激情网| 欧洲亚洲在线视频| 久久露脸国产精品| 国产精自产拍久久久久久蜜| 日本久久久久亚洲中字幕| 欧美高跟鞋交xxxxhd| 成人国产精品色哟哟| 亚洲2020天天堂在线观看| 久久精品国产欧美激情| 亚洲影视九九影院在线观看| 国产精品福利小视频| 欧美三级欧美成人高清www| 日韩二区三区在线| 亚洲国产婷婷香蕉久久久久久| 欧美—级a级欧美特级ar全黄| 91tv亚洲精品香蕉国产一区7ujn| 国产精品久久9| 美女性感视频久久久| 自拍偷拍亚洲欧美| 亚洲国产精品嫩草影院久久| 性欧美亚洲xxxx乳在线观看| 91亚洲精品一区| 国产精品91久久久| 久久精品成人欧美大片古装| 国产日本欧美一区二区三区| 在线免费观看羞羞视频一区二区| 欧美成人h版在线观看| 国产丝袜一区二区三区| 国产欧美日韩中文| 久久亚洲一区二区三区四区五区高| 亚洲一区第一页| 亚洲最大av在线| 久久久av电影| 国产精品亚洲综合天堂夜夜| 亚洲欧美日韩第一区| 美女性感视频久久久| 国产视频精品免费播放| 亚洲男人天堂网| 国产一区二中文字幕在线看| 欧美性猛交xxxxx水多| 精品久久久久久国产91| 国产精品视频精品视频| 97福利一区二区| 亚洲激情久久久| 亚洲xxx大片| 91午夜在线播放| 久久偷看各类女兵18女厕嘘嘘| 日韩av免费在线播放| 3344国产精品免费看| 精品亚洲国产成av人片传媒| 亚洲国产精品成人av| 亚洲男人的天堂在线| 国产精品国产亚洲伊人久久| 国产亚洲欧美日韩美女| 日韩美女视频在线观看| 精品国产一区二区三区久久狼黑人| 日韩一区二区三区xxxx| 色综合影院在线| 欧美一区二区.| 亚洲最大的免费| 97超碰国产精品女人人人爽| 欧美日韩激情美女| 国产午夜精品一区二区三区| 成人两性免费视频| 国产精品久久二区| 亚洲va久久久噜噜噜| 精品成人乱色一区二区| 91超碰caoporn97人人| 中文字幕国产亚洲2019| 欧美韩日一区二区| 伊人久久大香线蕉av一区二区| 一区二区三区回区在观看免费视频| 亚洲成色www8888| 在线视频中文亚洲| 亚洲字幕一区二区| 久久久久国色av免费观看性色| 亚洲精品美女在线| 欧美一级视频一区二区| 欧美贵妇videos办公室| 亚洲图片在线综合| 色中色综合影院手机版在线观看| 81精品国产乱码久久久久久| 国产精品成人av性教育| 在线电影欧美日韩一区二区私密| 亚洲男人第一av网站| 国产免费一区二区三区在线能观看| 久久人人爽人人爽人人片亚洲| 欧美一区二区大胆人体摄影专业网站| 欧美另类高清videos| 亚洲一区二区三区sesese| 久久亚洲精品网站| 欧美日韩视频免费播放| 黑人巨大精品欧美一区二区| 精品一区电影国产| 国产精品久久久久久久久久新婚| 热门国产精品亚洲第一区在线| 国产一区二区动漫| 日韩一区视频在线| 日韩精品视频观看| 一区二区在线视频| 成人精品视频99在线观看免费| 国产成人精品免高潮费视频| 国产精品久久久久久久久借妻| 精品视频久久久久久| 日韩人在线观看| 日韩网站免费观看高清| 欧美日韩综合视频| 一区二区亚洲欧洲国产日韩| 欧美—级高清免费播放| 26uuu亚洲国产精品| 视频在线观看一区二区| 国产精品专区h在线观看| 国产精品视频久久久| 综合网日日天干夜夜久久| 夜夜嗨av色一区二区不卡| 国产精品∨欧美精品v日韩精品|