GridView, ListView a ListBox – k čemu se každý z těchto prvků hodí

V této ukázce budu zkoumat možnosti těchto 3 prvků. V každém který podporuje

Odvození GridView:
Object -> DependencyObject -> UIElement -> FrameworkElement -> Control -> ItemsControl -> Selector -> ListViewBase, ISemanticZoomInformation -> GridView

Odvození ListView:
Object -> DependencyObject -> UIElement -> FrameworkElement -> Control -> ItemsControl -> Selector -> ListViewBase, ISemanticZoomInformation -> ListView

Odvození ListBox:
Object -> DependencyObject -> UIElement -> FrameworkElement -> Control -> ItemsControl -> Selector -> ListBox

GridViewItem, ListViewItem a ListBoxItem mají svou nadřazenou hiearchii úplně stejnou a to sice tuto:
Object -> DependencyObject -> UIElement -> FrameworkElement -> Control -> ContentControl -> SelectorItem -> GridViewItem, ListViewItem, ListBoxItem

ListViewBase, ISemanticZoomInformation

Metody navíc oproti třídě Selector:

  • void CompleteViewChange()
  • void CompleteViewChangeFrom(SemanticZoomLocation, SemanticZoomLocation)
  • void CompleteViewChangeTo(SemanticZoomLocation source, SemanticZoomLocation destination)
  • IAsyncOperation LoadMoreItemsAsync()
  • void MakeVisible(SemanticZoomLocation item)
  • void ScrollIntoView(object item, ScrollIntoViewAlignment alignment)
  • void ScrollIntoView(object item)
  • void SelectAll()
  • void StartViewChangeFrom(SemanticZoomLocation source, SemanticZoomLocation destination)
  • void StartViewChangeTo(SemanticZoomLocation source, SemanticZoomLocation destination)
  • bool CanDragItems { set; get; }
  • bool CanReorderItems { set; get; }
  • double DataFetchSize { set; get; }
  • object Header { set; get; } – Je to skoro jako HeaderTemplate, akorát HeaderTemplate se nastavuje v XAMLu a Header v C# kódu, kde pouze vytvoříte Content a přiřadíte. Můžete takto třeba programově měnit hlavičku.
  • DataTemplate HeaderTemplate { set; get; } – Protože ListView/GridView negeneruje hlavičku samo, musíte si ji sami vytvořit pokud ji chcete. Opět – nedoporučuji provádět v C# ale v Xamlu. Nezapomeňte dát všem hlavičkám stejnou šířku jako mají sloupce v ItemTemplate – toto si musíte hlídat vy, program se o toto nestará.
  • TransitionCollection HeaderTransitions { set; get; }
  • double IncrementalLoadingThreshold { set; get; }
  • IncrementalLoadingTrigger IncrementalLoadingTrigger { set; get; }
  • bool IsActiveView { set; get; }
  • bool IsItemClickEnabled { set; get; }
  • bool IsSwipeEnabled { set; get; }
  • bool IsZoomedInView { set; get; }
  • IList SelectedItems { get; } – Vrací mi vybrané položky, které už pak stačí pouze přetypovat na typ používaný v DataContext, abych mohl používat všechny metody typu.
  • ListViewSelectionMode SelectionMode { set; get; } – Můžete sem dát tyto hodnoty:

    None – žádná položka nepůjde vybrat, všechny aktivní položky však budou i nadále aktivní.
    Single – Půjde vybrat pouze 1 položka. Pokud kliknete na jinou položku než byla vybrána, přesune se zaškrtnutí na tuto položku. Položku odeberete stejně jako jste ji vybrali – tak že na ni kliknete.
    Multiple – Klikem po jedné položce můžete vybrat více položek, po opětovném kliknutí danou položku odeberete. Extended – Můžete vybrat více položek skrze shift nebo ctrl. Pokud máte vybrané položky a kliknete na jinou položku omylem, vybere se vám tato nová položka.

  • SemanticZoom SemanticZoomOwner { set; get; }
  • event DragItemsStartingEventHandler DragItemsStarting
  • event ItemClickEventHandler ItemClick

Selector

Má navíc oproti třídě ItemsControl tyto chráněné položky:

  • static bool GetIsSelectionActive(Windows.UI.Xaml.DependencyObject element)
  • bool? IsSynchronizedWithCurrentItem { set; get; }
  • int SelectedIndex { set; get; } – Co vrací – viz. tabulka níže
  • object SelectedItem { set; get; } – Co vrací – viz. tabulka níže
  • object SelectedValue { set; get; } – Co vrací – viz. tabulka níže
  • string SelectedValuePath { set; get; } – Můžete určit, kterou vlastnost místo DataContext‘;u místo celé položky chcete vracet v SelectedValuePath.
  • event SelectionChangedEventHandler SelectionChanged

SelectionMode SelectedIndex SelectedItem SelectedValue SelectedValuePath
None -1 null null To co mu zadáte, při změně výběru položek se nemění
Single Index zvolené položky Objekt zvolené položky Objekt zvolené položky To co mu zadáte, při změně výběru položek se nemění
Multiple Index první vybrané položky Objekt první vybrané položky Objekt první vybrané položky To co mu zadáte, při změně výběru položek se nemění
Extended Index první vybrané položky Objekt první vybrané položky Objekt první vybrané položky To co mu zadáte, při změně výběru položek se nemění

ItemsControl

Má navíc oproti třídě Control:

  • void ClearContainerForItemOverride(DependencyObject element, object item)
  • DependencyObject GetContainerForItemOverride()
  • bool IsItemItsOwnContainerOverride(object item)
  • void PrepareContainerForItemOverride(Windows.UI.Xaml.DependencyObject element, object item)

Má navíc oproti třídě ItemsControl tyto veřejné položky:

  • static ItemsControl GetItemsOwner(DependencyObject element)
  • static Windows.UI.Xaml.Controls.ItemsControl ItemsControlFromItemContainer(Windows.UI.Xaml.DependencyObject container)
  • string DisplayMemberPath { set; get; }
  • IObservableVector GroupStyle { get; }
  • GroupStyleSelector GroupStyleSelector { set; get; }
  • bool IsGrouping { get; }
  • ItemContainerGenerator ItemContainerGenerator { get; }
  • Style ItemContainerStyle { set; get; }
  • StyleSelector Ite mContainerStyleSelector { se t; get; }
  • TransitionCollection ItemContainerTransitions { set; get; }
  • ItemCollection Items { get; } – Pokud chcete přidávat přímo položky odvozené od ListBoxItem/ListViewItem/GridViewItem. Nicméně já tuto cestu nedoporučuji, viz níže.
  • ItemsPanelTemplate ItemsPanel { set; get; } – Šablona prvků, které se načtou z ItemsSource.
  • object ItemsSource { set; get; } – Objekt ObservableCollection obsahující jednotlivé položky, které si uživatel přeje zobrazit.
  • DataTemplate ItemTemplate { set; get; } – Šablona jedné položky.
  • DataTemplateSelector ItemTemplateSelector { set; get; } – slouží k dynamickému přiřazení různých DataTemplate podle různých vlastností. Pro více informací se kouknete na https://stackoverflow.com/questions/2302250/how-to-style-different-items-differently-when-using-data-template-in-xaml/2304265#2304265

Control

O žádné prvky třídy Control se zde nebudeme více zabývat.

FrameworkElement

Z této třídy zde budu zkoumat pouze jednu vlastnost:

  • object DataContext { set; get; } – objekt, ze kterého se načítají při DataBinding’u jednotlivé vlastnosti.

GridView

Hodí se když:
Zobrazujete věci horizontálně

Nehodí se když:
Potřebujete kompabilitu s klasickými prvky .NETu

Metody navíc oproti třídě ListViewBase: žádné

ListView

Hodí se když:
Zobrazujete věci vertikálně

Nehodí se když:
Potřebujete kompabilitu s klasickými prvky .NETu

Metody navíc oproti třídě ListViewBase: žádné

ListBox

Hodí se když:
Potřebujete zpětnou kompatibilitu

Nehodí se když:
Prvek musí být optimalizovaný pro dotykové ovládání

Metody navíc oproti třídě Selector:

  • void ScrollIntoView(object item) –
  • void SelectAll()
  • IList>object<
    SelectedItems { get; }

  • SelectionMode SelectionMode { set; get; }
  • SelectorItem

    Má navíc tyto vlastnosti oproti položce ContentControl:

    • bool IsSelected { get; set; }

    GridViewItem

    Má navíc oproti třídě SelectorItem:

    • ListViewItemTemplateSettings TemplateSettings { get; }

    Běžně se od této třídy neodvozuje a nepíše se prezentační kód v C#. Místo toho se pouze vytvoří třída s veřejnými vlastnostmi a dále se namapují tyto vlastnosti pomocí DataBinding’u na šablonu, kterou máte v … XAML kód šablony …

    ListViewItem

    Má navíc oproti třídě SelectorItem:

    • ListViewItemTemplateSettings TemplateSettings { get; }

    Běžně se od této třídy neodvozuje a nepíše se prezentační kód v C#. Místo toho se pouze vytvoří třída s veřejnými vlastnostmi a dále se namapují tyto vlastnosti pomocí DataBinding’u na šablonu, kterou máte v … XAML kód šablony …

    ListBoxItem

    Má navíc oproti třídě SelectorItem: nic

    Běžně se od této třídy neodvozuje a nepíše se prezentační kód v C#. Místo toho se pouze vytvoří třída s veřejnými vlastnostmi a dále se namapují tyto vlastnosti pomocí DataBinding’u na šablonu, kterou máte v … XAML kód šablony …

    Třídy dědící od INotifyPropertyChanged

    Základem tohoto návodu je implementovat jak ve třídě jedné položky tak u obalující kolekce této třídy.
    1) Prvním krokem je tedy definovat třídu položky.

    C#
    public class Item
    {
    }

    2) Vytvořte veřejné vlastnosti a soukromé proměnné, které budou obsahovat data položky.

    C#
    string header = "";
    public string Header
    {
        get
        {
            return header;
        }
        set
        {
            header = value;
        }
    }
    string description = "";
    public string Description
    {
        get
        {
            return description;
        }
        set
        {
            description = value;
        }
    }

    3) Napište si třídu odvozenou od INotifyPropertyChanged, která může vypadat třeba takto:

    C#
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    namespace W8Learn.DataControls
    {
        public class NotifyPropertyChanged : INotifyPropertyChanged
        {
            protected void OnPropertyChanged(object sourceClass, string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(sourceClass, new PropertyChangedEventArgs(propertyName));
                }
            }
            public event PropertyChangedEventHandler PropertyChanged;
        }
    }

    4) Odvoďte od této vytvořené třídy vaši třídu položky a doplňte volání OnPropertyChanged() do set’u každé vlastnosti, na kterou chcete být upozorňován pokud se změní.

    C#
    public class Item : NotifyPropertyChanged
    {
        string header = "";
        public string Header
        {
            get
            {
                return header;
            }
            set
            {
                OnPropertyChanged(this, "Header");
                header = value;
            }
        }
        string description = "";
        public string Description
        {
            get
            {
                return description;
            }
            set
            {
                OnPropertyChanged(this, "Description");
                description = value;
            }
        }
    }

    5) Vytvořte třídu NotifyPropertyChangedCollection , kde T bude typ položky. Tuto třídu můžete používat při všech kolekcích okolo prvků, které implementují INotifyPropertyChanged.

    C#
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    u
    sing System.Text;
    using System.Threading.Tasks;
    //-Jmenny prostor System.Reflection se musi importovat rucne
    using System.Reflection;
    namespace W8Learn.DataControls
    {
        class NotifyPropertyChangedCollection<t> : NotifyPropertyChanged
        {
            /// <summary>
            /// Musi to byt typ ObservableCollection protoze T implementuje rozhrani INotifyPropertyChanged, a s nim umi pracovat pouze ObservableCollection
            /// </summary>
            public ObservableCollection<t> Collection = new ObservableCollection<t>();
            /// <summary>
            /// Nemuze byt staticka, protoze bych musel ke kazdemu volani metody zadavat i typ T
            /// </summary>
            /// <param name="propertyClass">
            /// <param name="propertyName">
            /// <returns> </returns>
            public string GetPropertyValue(object propertyClass, string propertyName)
            {
                object o = propertyClass.GetType().GetRuntimeProperty(propertyName).GetValue(propertyClass);
                if (o != null)
                {
                    return o.ToString();
                }
                return string.Empty;
            }
        }
    } </t> </t> </t>

    6) Napište třídu ItemCollection – obalující třídu na položky. Přidejte do její proměnné kolekce každou položku a každé položce přiřaďte stejný handler události – metodu OnPropertyChanged v této třídě. Je to sice zde zbytečné protože ve W8 se po updatu vlastnosti Text controlu TextBlock se tento nový text nevykreslí, ale v klasické WPF aplikaci by se vykreslil.

    C#
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    namespace W8Learn.DataControls
    {
        class ItemCollection : NotifyPropertyChangedCollection<Item>
        {
            public ItemCollection()
            {
                for (int i = 0; i < 100; i++)
                {
                    Item item = new Item();
                    item.Header = "Polozka #" + i.ToString();
                    item.Description = "";
                    item.PropertyChanged += item_PropertyChanged;
                    Collection.Add(item);
                }
            }
            void item_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
            {
                OnPropertyChanged(sender, e.PropertyName);
            }
        }
    } </Item>

    7) To je všechno. Nyní už jen u GridView/ListView/ListBox přiřaďte do vlastnosti ItemsSource tuto vlastnost Collection vytvořené třídy ItemCollection a nastavte mód data bindingu u prvků které chcete ukládat do třídy Item na TwoWay.]]>

    Napsat komentář

    Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *