程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Windows 8 Store Apps學習(12) GridView控件特性

Windows 8 Store Apps學習(12) GridView控件特性

編輯:關於.NET

GridView控件特性: 拖動項, 項尺寸可變, 分組顯示

介紹

重新想象 Windows 8 Store Apps 之 GridView

拖動項 - 在 GridView 內拖動 item 以對 item 排序, 拖動 item 到 GridView 外的指定位置以刪除 item

項尺寸可變 - 指定 GirdView 中每個 item 所占尺寸

分組顯示 - 分組顯示集合數據

示例

1、演示如何在 GridView 內拖動 item 以對 item 排序,以及如何拖動 item 到 GridView 外的指定位 置以刪除 item

GridView/DragItem.xaml

<Page
    x:Class="XamlDemo.Controls.GridView.DragItem"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:XamlDemo.Controls.GridView"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    
    <Page.Resources>
        <DataTemplate x:Key="ItemTemplate">
            <StackPanel Orientation="Vertical">
                <TextBlock TextWrapping="Wrap" FontSize="14.667" Text="{Binding Name}" HorizontalAlignment="Left" />
                <TextBlock TextWrapping="Wrap" FontSize="14.667" Text="{Binding Age}" HorizontalAlignment="Left"/>
            </StackPanel>
        </DataTemplate>
        <Style x:Key="ItemContainerStyle"  TargetType="GridViewItem">
            <Setter Property="Width" Value="292" />
            <Setter Property="Height" Value="80" />
            <!--
                即使將 Margin 設置為“0”,也無法去掉 item 之間的 margin
                如果想要去掉 item 之間的 margin,請將此 Margin 屬性設置為“-4”
            -->
            <Setter Property="Margin" Value="0" />
            <Setter Property="Background" Value="Blue" />
        </Style>
        <ItemsPanelTemplate x:Key="ItemsPanel">
            <!--
                注:WrapGrid 繼承了 VirtualizingPanel,而 VariableSizedWrapGrid 並未繼承 VirtualizingPanel
            -->
            <WrapGrid MaximumRowsOrColumns="3" Orientation="Vertical" VerticalChildrenAlignment="Top" HorizontalChildrenAlignment="Left" />
        </ItemsPanelTemplate>
    </Page.Resources>
    
    <Grid Background="Transparent">
        <StackPanel Margin="120 0 0 0">
    
            <TextBlock Name="lblMsg" FontSize="14.667" Text="通過拖動 GirdView 中的 Item 進行排序" />
    
            <GridView x:Name="gridView" VerticalAlignment="Top" Margin="0 10 10 0" BorderThickness="1" BorderBrush="Red" Background="LightBlue"
                      ItemTemplate="{StaticResource ItemTemplate}"
                      ItemContainerStyle="{StaticResource ItemContainerStyle}"
                      ItemsPanel="{StaticResource ItemsPanel}"
                      IsSwipeEnabled="True" IsItemClickEnabled="True"
                      CanDragItems="True" CanReorderItems="True" AllowDrop="True"
                      DragItemsStarting="gridView_DragItemsStarting_1" />
    
            <!--拖動 item 到此處以刪除 item-->
            <Grid Name="gridDelete" Margin="0 10 0 0" AllowDrop="True" Drop="gridDelete_Drop_1" DragEnter="gridDelete_DragEnter_1" DragLeave="gridDelete_DragLeave_1" 

DragOver="gridDelete_DragOver_1">
                <Rectangle Width="300" Height="100" StrokeThickness="1" StrokeDashArray="2" Stroke="Red" Fill="Blue" />
                <TextBlock FontSize="26.667" Text="拖動到此處以刪除" TextAlignment="Center" VerticalAlignment="Center" />
            </Grid>
                
        </StackPanel>
    </Grid>
</Page>

GridView/DragItem.xaml.cs

/*
 * 演示如何在 GridView 內拖動 item 以對 item 排序,以及如何拖動 item 到 GridView 外的指定位置以

刪除 item
 * 
 * GridView - 網格控件
 *     CanDragItems - item 是否可被拖動
 *     CanReorderItems - 是否可通過拖動 item 來排序
 *     AllowDrop - 是否可在 GridView 中 drop
 *     DragItemsStarting - item 開始被拖動時所觸發的事件(事件參數 DragItemsStartingEventArgs)
 *      
 * DragItemsStartingEventArgs
 *     Items - 被拖動的 items 集合
 *     Cancel - 是否取消拖動操作
 *     Data - 一個 DataPackage 類型的對象,用於傳遞數據(與 DataPackage 在剪切板和 Share Contract 中的作用一樣)
 *     
 * 
 * 注:
 * drag-drop 間傳遞數據,clipboard 間傳遞數據,Share Contract 間傳遞數據,以及其他場景的數據傳遞均可通過 DataPackage 類型的對象來完成
 * 本例沒有通過 DataPackage 來傳遞數據(太麻煩),而是通過一個私有字段來傳遞數據(比較簡單)
 */
    
using System.Collections.ObjectModel;
using Windows.UI.Xaml.Controls;
using System.Linq;
using XamlDemo.Model;
using Windows.UI.Xaml;
using System.Diagnostics;
    
namespace XamlDemo.Controls.GridView
{
    public sealed partial class DragItem : Page
    {
        // 數據源
        private ObservableCollection<Employee> _dataSource;
        // 拖動中的 Employee 對象
        private Employee _draggingEmployee;
    
        public DragItem()
        {
            this.InitializeComponent();
                
            // 綁定數據
            _dataSource = new ObservableCollection<Employee>(TestData.GetEmployees());
            gridView.ItemsSource = _dataSource;
    
            // GridView 中的 items 發生變化時觸發的事件
            gridView.ItemContainerGenerator.ItemsChanged += ItemContainerGenerator_ItemsChanged;
        }
    
        void ItemContainerGenerator_ItemsChanged(object sender, Windows.UI.Xaml.Controls.Primitives.ItemsChangedEventArgs e)
        {
            if (e.OldPosition.Index > -1)
            {
                // 在 GridView 中 drop 了 item,且排序發生了變化
    
                var oldIndex = _dataSource.IndexOf(_draggingEmployee); // 被拖動的 Employee 對象的原位置
                var newIndex = e.Position.Index + e.Position.Offset; // 被拖動的 Employee 對象的新位置
    
                // 修改數據源
                _dataSource.Move(oldIndex, newIndex);
    
                _draggingEmployee = null;
            }
                
        }
    
        // GridView 中的 item 開始被拖動時
        private void gridView_DragItemsStarting_1(object sender, DragItemsStartingEventArgs e)
        {
            _draggingEmployee = e.Items.First() as Employee;
        }
    
    
        // GridView 中的 item 被 drop 到了指定的位置後
        private void gridDelete_Drop_1(object sender, DragEventArgs e)
        {
            // 從數據源中刪除指定的 Employee 對象
            _dataSource.Remove(_draggingEmployee);
            _draggingEmployee = null;
    
            // 在 gridDelete 放下了拖動項
            Debug.WriteLine("Drop");
        }
    
        private void gridDelete_DragEnter_1(object sender, DragEventArgs e)
        {
            // 拖動項被拖進 gridDelete 了
            Debug.WriteLine("DragEnter");
        }
    
        private void gridDelete_DragLeave_1(object sender, DragEventArgs e)
        {
            // 拖動項被拖出 gridDelete 了
            Debug.WriteLine("DragLeave");
        }
    
        private void gridDelete_DragOver_1(object sender, DragEventArgs e)
        {
            // 拖動項在 gridDelete 上面拖動著
            Debug.WriteLine("DragOver");
        }
    }
}

2、演示如何指定 GirdView 中每個 item 所占尺寸

GridView/ColorModel.cs

using 

Windows.UI.Xaml.Media;
    
namespace XamlDemo.Controls.GridView
{
    /// <summary>
    /// 用於綁定到 VariableSized.xaml 中的 GridView 的數據實體模型
    /// </summary>
    class ColorModel
    {
        public string ColorName { get; set; }
        public SolidColorBrush ColorValue { get; set; }
    
        // 此對象所占的網格的列合並數
        public int ColSpan { get; set; }
        // 此對象所占的網格的行合並數
        public int RowSpan { get; set; }
    }
}

GridView/MyGridView.cs

/*
 * 此控件可以指定 GridView 的每個 item 所占網格的列合並數和行合並數
 */
    
using System;
using System.Diagnostics;
    
namespace XamlDemo.Controls.GridView
{
    public class MyGridView : Windows.UI.Xaml.Controls.GridView
    {
        protected override void PrepareContainerForItemOverride(Windows.UI.Xaml.DependencyObject element, object item)
        {
            try
            {
                // 指定 VariableSizedWrapGrid 的 ColumnSpan 和 RowSpan
    
                dynamic dynamicItem = item;
                element.SetValue(Windows.UI.Xaml.Controls.VariableSizedWrapGrid.ColumnSpanProperty, dynamicItem.ColSpan);
                element.SetValue(Windows.UI.Xaml.Controls.VariableSizedWrapGrid.RowSpanProperty, dynamicItem.RowSpan);
            }
            catch(Exception ex)
            {
                // 當有異常情況發生時(比如:item 沒有 ColSpan 屬性或 RowSpan 屬性)
    
                Debug.WriteLine(ex.ToString());
    
                element.SetValue(Windows.UI.Xaml.Controls.VariableSizedWrapGrid.ColumnSpanProperty, 1);
                element.SetValue(Windows.UI.Xaml.Controls.VariableSizedWrapGrid.RowSpanProperty, 1);
            }
            finally
            {
                base.PrepareContainerForItemOverride(element, item);
            }
        }
    }
}

GridView/VariableSized.xaml

<Page
    x:Class="XamlDemo.Controls.GridView.VariableSized"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:XamlDemo.Controls.GridView"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    
    <Page.Resources>
        <DataTemplate x:Key="ItemTemplate">
            <Grid Background="{Binding ColorValue}">
                <Grid Background="Black" VerticalAlignment="Top" HorizontalAlignment="Stretch" Opacity="0.7">
                    <TextBlock Text="{Binding ColorName}" />
                </Grid>
            </Grid>
        </DataTemplate>
        <Style x:Key="ItemContainerStyle" TargetType="GridViewItem">
            <Setter Property="VerticalContentAlignment" Value="Stretch" />
            <Setter Property="HorizontalContentAlignment" Value="Stretch" />
            <!--
                即使將 Margin 設置為“0”,也無法去掉 item 之間的 margin
                如果想要去掉 item 之間的 margin,請將此 Margin 屬性設置為“-4”
            -->
            <Setter Property="Margin" Value="-4" />
        </Style>
        <ItemsPanelTemplate x:Key="ItemsPanel">
            <!--
                注:WrapGrid 繼承了 VirtualizingPanel,而 VariableSizedWrapGrid 並未繼承 

VirtualizingPanel
                
                ItemWidth, ItemHeight - 每個網格的寬和高
                ColumnSpan, RowSpan - item 所在網格的列合並數和行合並數,本例在後台指定了這兩個

屬性,參見 MyGridView.cs
            -->
            <VariableSizedWrapGrid MaximumRowsOrColumns="4" Orientation="Vertical" ItemWidth="100" ItemHeight="100" Height="400" />
        </ItemsPanelTemplate>
    
    </Page.Resources>
    
    <Grid Background="Transparent">
        <StackPanel Margin="120 0 0 0">
    
            <!--
                使用 MyGridView 控件,其重寫了 GridView 的 PrepareContainerForItemOverride() 方法,詳見 MyGridView.cs
            -->
            <local:MyGridView x:Name="gridView" Height="400" VerticalAlignment="Top" 

Margin="0 10 10 0" Background="Yellow"
                              ItemTemplate="{StaticResource ItemTemplate}"
                              ItemContainerStyle="{StaticResource ItemContainerStyle}"
                              ItemsPanel="{StaticResource ItemsPanel}"
                              IsItemClickEnabled="False" IsSwipeEnabled="False" SelectionMode="None"
                              ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollBarVisibility="Auto">
            </local:MyGridView>
    
        </StackPanel>
    </Grid>
</Page>

GridView/VariableSized.xaml.cs

/*
 * 演示如何指定 GirdView 中每個 item 所占尺寸
 * GridView 是一個網格控件,這裡所謂的每個 item 所占尺寸,其本質上就是 item 所在網格的列合並數和

行合並數
 * 
 * 要實現此需求的話:
 * 1、必須使用 VariableSizedWrapGrid,具體見 VariableSized.xaml
 * 2、需要重寫 GridView 的 PrepareContainerForItemOverride() 方法,具體見 MyGridView.cs
 */
    
using System.Reflection;
using System.Linq;
using System.Collections.Generic;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using System;
using Windows.UI;
    
namespace XamlDemo.Controls.GridView
{
    public sealed partial class VariableSized : Page
    {
        public VariableSized()
        {
            this.InitializeComponent();
    
            BindData();
        }
    
        private void BindData()
        {
            Random random = new Random();
    
            // 獲取 Windows.UI.Colors 的全部數據
            List<ColorModel> colors = typeof(Colors)  // typeof 在 System.Reflection 命名空間下
                .GetRuntimeProperties()
                .Select(c => new ColorModel
                {
                    ColorName = c.Name,
                    ColorValue = new SolidColorBrush((Color)c.GetValue(null)),
                    ColSpan = random.Next(1, 3), // 此對象所占網格的列合並數
                    RowSpan = random.Next(1, 3) // 此對象所占網格的行合並數
                })
                .ToList();
    
            // 綁定數據
            gridView.ItemsSource = colors;
        }
    }
}

3、演示如何分組顯示集合數據(關於分組的示例會和之後的 SemanticZoom 一起寫)

GridView/Group.xaml

<Page
    x:Class="XamlDemo.Controls.GridView.Group"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:XamlDemo.Controls.GridView"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    
    <Grid Background="Transparent">
        <StackPanel Margin="120 0 0 0">
    
            <TextBlock Name="lblMsg" FontSize="14.667">
                <Run>關於 GridView 的分組顯示請參見本 app 的索引頁 Index.xaml 和Index.xaml.cs</Run>
                <LineBreak />
                <Run>分組的功能來源於 ItemsControl(GridView, ListView, FlipView, ListBox等均繼承了 ItemsControl)</Run>
            </TextBlock>
    
        </StackPanel>
    </Grid>
</Page>

OK

[源碼下載]:http://files.cnblogs.com/webabcd/Windows8.rar

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved