Windows 10 - 控制項(集合類)的詳細介紹

來源:互聯網
上載者:User
樣本

1、自訂 ItemsControl(自訂 GirdView 使其每個 item 佔用不同大小的空間)
Controls/CollectionControl/ItemsControlDemo/MyItemsControlDemo.xaml

<Pagex:Class="Windows10.Controls.CollectionControl.ItemsControlDemo.MyItemsControlDemo"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="using:Windows10.Controls.CollectionControl.ItemsControlDemo"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" 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" /><Setter Property="Margin" Value="0" /><Setter Property="Padding" Value="0" /></Style><ItemsPanelTemplate x:Key="ItemsPanel"><VariableSizedWrapGrid MaximumRowsOrColumns="8" Orientation="Horizontal" ItemWidth="100" ItemHeight="100"  /></ItemsPanelTemplate></Page.Resources><Grid Background="Transparent" Margin="10 0 10 10"><!--使用 MyGridView 控制項,其重寫了 GridView 的 PrepareContainerForItemOverride() 方法,詳見 MyGridView.cs--><local:MyGridView x:Name="gridView" Width="812" VerticalAlignment="Top" HorizontalAlignment="Left"  ItemTemplate="{StaticResource ItemTemplate}"  ItemContainerStyle="{StaticResource ItemContainerStyle}"  ItemsPanel="{StaticResource ItemsPanel}"                           IsItemClickEnabled="False"                           SelectionMode="None"></local:MyGridView></Grid></Page>

Controls/CollectionControl/ItemsControlDemo/MyItemsControlDemo.xaml.cs

/* * ItemsControl - 集合控制項(繼承自 Control, 請參見 /Controls/BaseControl/ControlDemo/) *     protected virtual void PrepareContainerForItemOverride(DependencyObject element, object item); - 為 item 準備 container 時 *         element - item 的 container *         item - item *          *  * 本例用於示範如何使 GirdView 中的每個 item 佔用不同大小的空間 * 1、布局控制項要使用 VariableSizedWrapGrid(利用其 RowSpan 和 ColumnSpan 來實現 item 佔用不同大小的空間),需要注意的是其並非是虛擬化布局控制項 * 2、自訂 GridView,並重寫 ItemsControl 的 protected override void PrepareContainerForItemOverride(DependencyObject element, object item) 方法 *    然後設定每個 item 的 VariableSizedWrapGrid.RowSpan 和 VariableSizedWrapGrid.ColumnSpan */using System;using System.Collections.Generic;using System.Linq;using Windows.UI;using Windows.UI.Xaml;using Windows.UI.Xaml.Controls;using Windows.UI.Xaml.Media;using System.Reflection;namespace Windows10.Controls.CollectionControl.ItemsControlDemo{public sealed partial class MyItemsControlDemo : Page    {public MyItemsControlDemo()        {this.InitializeComponent();               BindData();        }private void BindData()        {            Random random = new Random();// 擷取 Windows.UI.Colors 的全部資料Type type = typeof(Colors);            List<ColorModel> colors = type.GetRuntimeProperties() // GetRuntimeProperties() 在 System.Reflection 命名空間下.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;        }    }/// <summary>/// 用於資料繫結的對象/// </summary>public class ColorModel    {public string ColorName { get; set; }public SolidColorBrush ColorValue { get; set; }// 此對象所佔的網格的列合并數public int ColSpan { get; set; }// 此對象所佔的網格的行合并數public int RowSpan { get; set; }    }/// <summary>/// 自訂 GridView,重寫 ItemsControl 的 protected override void PrepareContainerForItemOverride(DependencyObject element, object item) 方法/// 用於指定 GridView 的每個 item 所佔網格的列合并數和行合并數/// </summary>public class MyGridView : GridView    {protected override void PrepareContainerForItemOverride(DependencyObject element, object item)        {try{// 設定每個 item 的 VariableSizedWrapGrid.RowSpan 和 VariableSizedWrapGrid.ColumnSpan, 從而實現每個 item 佔用不同大小的空間// 僅為示範用,由於這裡的 ColSpan 和 RowSpan 都是隨機計算的,所以可能會出現空白空間dynamic dynamicItem = item;                element.SetValue(VariableSizedWrapGrid.ColumnSpanProperty, dynamicItem.ColSpan);                element.SetValue(VariableSizedWrapGrid.RowSpanProperty, dynamicItem.RowSpan);            }catch (Exception ex)            {var ignore = ex;// 當有異常情況發生時(比如:item 沒有 ColSpan 屬性或 RowSpan 屬性)element.SetValue(VariableSizedWrapGrid.ColumnSpanProperty, 1);                element.SetValue(VariableSizedWrapGrid.RowSpanProperty, 1);            }finally{base.PrepareContainerForItemOverride(element, item);            }        }    }}


2、自訂 ContentPresenter 實作類別似 GridViewItemPresenter 和 ListViewItemPresenter 的效果
Controls/CollectionControl/ItemsControlDemo/MyItemPresenter.cs

/* * 自訂 ContentPresenter 實作類別似 GridViewItemPresenter 和 ListViewItemPresenter 的效果 */using System;using Windows.Foundation;using Windows.UI;using Windows.UI.Xaml;using Windows.UI.Xaml.Controls;using Windows.UI.Xaml.Media;using Windows.UI.Xaml.Media.Animation;using Windows.UI.Xaml.Shapes;namespace Windows10.Controls.CollectionControl.ItemsControlDemo{class MyItemPresenter : ContentPresenter    {        Panel _container = null; // item 的容器(即在 DataTemplate 中定義的根項目,在樣本 MyItemPresenterDemo.xaml 中用的是 Grid)Rectangle _pointerOverBorder = null; // 滑鼠經過 item 時覆蓋在 item 上的 rectangleRectangle _focusVisual = null; // 選中 item 時覆蓋在 item 上的 rectangleStoryboard _pointerDownStoryboard = null; // 滑鼠按下時的動畫Storyboard _pointerUpStoryboard = null; // 滑鼠抬起時的動畫public MyItemPresenter()            : base()        {base.Margin = new Thickness(10);        }// override OnApplyTemplate() - 應用控制項範本時調用protected override void OnApplyTemplate()        {base.OnApplyTemplate();            _container = (Panel)VisualTreeHelper.GetChild(this, 0);        }// override GoToElementStateCore() - VisualState 轉換時調用(此方法僅在自訂 ContentPresenter 並將其應用於 GridView 或 ListView 的 ItemContainerStyle 時才會被調用)//     stateName - VisualState 的名字//     useTransitions - 是否使用 VisualTransition 過渡效果protected override bool GoToElementStateCore(string stateName, bool useTransitions)        {base.GoToElementStateCore(stateName, useTransitions);switch (stateName)            {// 正常狀態case "Normal":                    HidePointerOverVisuals();                    HideFocusVisuals();if (useTransitions)                    {                        StopPointerDownAnimation();                    }break;// 選中狀態case "Selected":case "PointerFocused":                    ShowFocusVisuals();if (useTransitions)                    {                        StopPointerDownAnimation();                    }break;// 取消選中狀態case "Unfocused":                    HideFocusVisuals();break;// 滑鼠經過狀態case "PointerOver":                    ShowPointerOverVisuals();if (useTransitions)                    {                        StopPointerDownAnimation();                    }break;// 滑鼠點擊狀態case "Pressed":case "PressedSelected":if (useTransitions)                    {                        StartPointerDownAnimation();                    }break;default: break;            }return true;        }private void StartPointerDownAnimation()        {if (_pointerDownStoryboard == null)                CreatePointerDownStoryboard();            _pointerDownStoryboard.Begin();        }private void StopPointerDownAnimation()        {if (_pointerUpStoryboard == null)                CreatePointerUpStoryboard();            _pointerUpStoryboard.Begin();        }private void ShowFocusVisuals()        {if (!FocusElementsAreCreated())                CreateFocusElements();            _focusVisual.Opacity = 1;        }private void HideFocusVisuals()        {if (FocusElementsAreCreated())                _focusVisual.Opacity = 0;        }private void ShowPointerOverVisuals()        {if (!PointerOverElementsAreCreated())                CreatePointerOverElements();            _pointerOverBorder.Opacity = 1;        }private void HidePointerOverVisuals()        {if (PointerOverElementsAreCreated())                _pointerOverBorder.Opacity = 0;        }private void CreatePointerDownStoryboard()        {/* * 用這種方式為 item 實現滑鼠按下的效果會報錯(Attempted to read or write protected memory. This is often an indication that other memory is corrupt.),不知道為什麼             * PointerDownThemeAnimation pointerDownAnimation = new PointerDownThemeAnimation();             * Storyboard.SetTarget(pointerDownAnimation, _container);             * Storyboard pointerDownStoryboard = new Storyboard();             * pointerDownStoryboard.Children.Add(pointerDownAnimation);             */DoubleAnimation da1 = new DoubleAnimation()            {                To = 0.9,                Duration = TimeSpan.FromMilliseconds(100)            };            DoubleAnimation da2 = new DoubleAnimation()            {                To = 0.9,                Duration = TimeSpan.FromMilliseconds(100)            };            Storyboard.SetTarget(da1, _container);            Storyboard.SetTargetProperty(da1, "(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)");            Storyboard.SetTarget(da2, _container);            Storyboard.SetTargetProperty(da2, "(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)");if (!(_container.RenderTransform is TransformGroup))            {                TransformGroup Group = new TransformGroup();                Group.Children.Add(new ScaleTransform());                _container.RenderTransform = Group;                _container.RenderTransformOrigin = new Point(0.5, 0.5);            }            _pointerDownStoryboard = new Storyboard();            _pointerDownStoryboard.Children.Add(da1);            _pointerDownStoryboard.Children.Add(da2);            _pointerDownStoryboard.Begin();        }private void CreatePointerUpStoryboard()        {            DoubleAnimation da1 = new DoubleAnimation()            {                To = 1,                Duration = TimeSpan.FromMilliseconds(100)            };            DoubleAnimation da2 = new DoubleAnimation()            {                To = 1,                Duration = TimeSpan.FromMilliseconds(100)            };            Storyboard.SetTarget(da1, _container);            Storyboard.SetTargetProperty(da1, "(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)");            Storyboard.SetTarget(da2, _container);            Storyboard.SetTargetProperty(da2, "(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)");if (!(_container.RenderTransform is TransformGroup))            {                TransformGroup Group = new TransformGroup();                Group.Children.Add(new ScaleTransform());                _container.RenderTransform = Group;                _container.RenderTransformOrigin = new Point(0.5, 0.5);            }            _pointerUpStoryboard = new Storyboard();            _pointerUpStoryboard.Children.Add(da1);            _pointerUpStoryboard.Children.Add(da2);            _pointerUpStoryboard.Begin();        }private void CreatePointerOverElements()        {            _pointerOverBorder = new Rectangle();            _pointerOverBorder.IsHitTestVisible = false;            _pointerOverBorder.Opacity = 0;// 這裡把顏色寫死了,僅為示範用,實際寫的時候要摘出來寫成相依性屬性_pointerOverBorder.Fill = new SolidColorBrush(Color.FromArgb(0x50, 0x50, 0x50, 0x50));            _container.Children.Insert(_container.Children.Count, _pointerOverBorder);        }private void CreateFocusElements()        {            _focusVisual = new Rectangle();            _focusVisual.IsHitTestVisible = false;            _focusVisual.Height = 10;            _focusVisual.VerticalAlignment = VerticalAlignment.Bottom;// 這裡把顏色寫死了,僅為示範用,實際寫的時候要摘出來寫成相依性屬性_focusVisual.Fill = new SolidColorBrush(Color.FromArgb(0xff, 0xff, 0x0, 0x0));            _container.Children.Insert(0, _focusVisual);        }private bool FocusElementsAreCreated()        {return _focusVisual != null;        }private bool PointerOverElementsAreCreated()        {return _pointerOverBorder != null;        }    }}

Controls/CollectionControl/ItemsControlDemo/MyItemPresenterDemo.xaml

<Pagex:Class="Windows10.Controls.CollectionControl.ItemsControlDemo.MyItemPresenterDemo"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="using:Windows10.Controls.CollectionControl.ItemsControlDemo"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"mc:Ignorable="d"><Page.Resources><Style x:Key="MyGridViewItemPresenterTemplate" TargetType="GridViewItem"><Setter Property="Background" Value="Transparent"/><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="GridViewItem"><!--自訂 ContentPresenter 實作類別似 GridViewItemPresenter 和 ListViewItemPresenter 的效果--><local:MyItemPresenter /></ControlTemplate></Setter.Value></Setter></Style></Page.Resources><Grid Background="Transparent"><GridView x:Name="gridView" SelectionMode="Single" Margin="10 0 10 10"                   ItemContainerStyle="{StaticResource MyGridViewItemPresenterTemplate}"><GridView.ItemTemplate><DataTemplate><Grid Height="100" Width="100" Background="Blue"><TextBlock x:Name="lblName" Text="{Binding Name}" Foreground="Yellow" /></Grid></DataTemplate></GridView.ItemTemplate></GridView></Grid></Page>

Controls/CollectionControl/ItemsControlDemo/MyItemPresenterDemo.xaml.cs

/* * 本例用於示範如何自訂 ContentPresenter 實作類別似 GridViewItemPresenter 和 ListViewItemPresenter 的效果 */using Windows.UI.Xaml.Controls;using Windows.UI.Xaml.Navigation;using Windows10.Common;namespace Windows10.Controls.CollectionControl.ItemsControlDemo{public sealed partial class MyItemPresenterDemo : Page    {public MyItemPresenterDemo()        {this.InitializeComponent();        }protected override void OnNavigatedTo(NavigationEventArgs e)        {            gridView.ItemsSource = TestData.GetEmployees();        }    }}



OK
[源碼下載]

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.