Makale Özeti

Bu makalemde sizlere Windows 8 Metro Style uygulama geliştirmede JavaScript yaklaşımını kullandığımızda DataBinding ile çalışmanız gerektiğinde birçok yerde kullanacağınız ListView kontrolünden bahsedeceğim.

Makale

Bu makalemde sizlere Windows 8 Metro Style uygulama geliştirmede JavaScript yaklaşımını kullandığımızda DataBinding ile çalışmanız gerektiğinde birçok yerde kullanacağınız ListView kontrolünden bahsedeceğim.

Listview kontrolü genel olarak bir datasource'da bulunan nesneleri listelemekte kullanılır. Temel olarak gösterimi iki farklı şekilde olabilir. Bunlar GirdLayout ve ListLayout'dur. GridLayout Windows 8 başlangıç ekranındaki gibi bir görünüm sunarken ListLayout nesnelerin alt alta listelenmesi şeklinde bir görünüm sunar.

Her iki görünümde de oluşturulacak nesneler için ItemTemplate kontrolünün kullanılması gerekmektedir. Şimdi isterseniz örnek bir Listview koduna ve ItemTemplate koduna bakalım, ardından ise Listview'in özelliklerini incelemeye devam edelim.

<div id="listUsers" data-win-control="WinJS.UI.ListView"></div>

Listview kullandığımız her zaman datasource'da bulunan her nesnenin ekrana render edilmesi gerekmektedir. Bu render işleminin nesne başına nasıl olacağını belirlenmesi için ItemTemplate kullanılması gerekmektedir. ItemView'i ise aşağıdaki gibi oluşturabiliriz. Gördüğünüz gibi div'imizin data-win-control özelliğine WinJS.Binding.Template tipini veriyoruz. Bu kontrolün içerisinde ise istediğimiz kontrolü kullanabiliyoruz. Datasource'da bulunan her nesne için render edilecek kontroller de bunlar olacaktır. Kullandığımız bu kontrollerin özelliklerine datasource'umuzdaki özellikleri atamak için data-win-bind özelliğini kullanıyoruz. Bu özelliğin içerisine kullandığımız kontrolün hangi özelliğine datasource'daki hangi özelliğin atanacağını kontrolözelliği:DataSourceÖzelliği şeklinde atıyoruz.

< div id="itemTemplateUsers" data-win-control="WinJS.Binding.Template">
    <div style="margin:5px">
        <img data-win-bind="src:UserImage" style="width:150px;height:150px" />
        <div data-win-bind="innerText:UserName" style="text-align:center"></div>
    </div>
</div>

Şimdi ise oluşturmuş olduğumuz bu ItemTemplate'in ListView tarafından kullanılmasını sağlamak gerekiyor. Bunun için ListView kontrolümüzün data-win-options özelliğine oluşturacağımız json nesnesi ile bu tanımlamayı yapmamız gerekiyor. Bu tanımlamayı aşağıdaki gibi yapabiliyoruz. ListView'in itemRenderer özelliğine oluşturmuş olduğumuz ItemTemplate'in id'sini vererek bu işlemi yapıyoruz. Bu sayede listview içerisinde oluşturulacak her nesne için itemTemplateUsers div'inin render edilmesini sağlıyoruz.

<div id="listUsers" data-win-control="WinJS.UI.ListView" data-win-options="{itemRenderer:itemTemplateUsers}"></div>

Şimdi isterseniz ListView kontrolünün belli başlı özelliklerini inceleyelim.

Event'ler
itemInvoked: Kullanıcı bir item üzerine tıkladığında veya dokunduğunda fırlatılacak event'tir.
keyboardNavigating: Kullanıcı klavyeyi kullanarak nesneler arasında dolaşıp seçimi değiştirdiğinde fırlatılacak event'tir.
loadingStateChanged: Listview'a data yüklemesi bittiğinde fırlatılacak event'tir. Ready ve Loading state'leri vardır.
selectionChanged: Kullanıcının seçtiği item değiştiğinde fırlatılacak event'tir.
selectionChanging: Kullanıcının seçtiği item değişmeye başladığında fırlatılacak event'tir.

Metod'lar:
elementFromIndex(index): Vermiş olduğumuz index'te bulunan elemanı geri döndüren metoddur.
indexOfElement(htmlObject): Vermiş olduğumuz eleman'ın index'ini geri döndüren metoddur.
loadMorePages(): Listview kontrolünün loadingBehavior özelliği incremental olarak set edildiği durumlarda bir sonraki set'in yüklenmesini tetikleyen metoddur.

Property'ler:
currentItem: Kullanıcının seçmiş olduğu item'ı alabileceğimiz veya kullanıcı yerine item seçebileceğimiz metoddur.
groupDataSource: Listview'in itemDataSource'unda bulunan nesnelerin gruplarının bilgisinin bulunduğu datasource'u taşır. Gruplama özelliğinde kullanılır. Bunun için ayrıca bir örnek yapacağız.
groupHeaderTemplate: Grup başlıklarının template'lerinin set edilmesi için kullanılır.
indexOfFirstVisible: Kullanıcı tarafından ekranda görülen ilk nesnenin index'ini verir.
indexOfLastVisible: Kullanıcı tarafından ekranda görülen son nesnenin index'ini verir.
itemDataSource: Listview içerisinde bulunacak item'lar için kullanılacak datasource nesnesini taşır.
itemTemplate: ListView içerisinde bulunacak item'lar render edilirken kullanılacak template'in set edilmesi için kullanılır.
layout: Listview'in GridLayout biçiminde mi yoksa ListLayout biçiminde mi yükleneceğinin belirlendiği özelliktir. GridLayout ve ListLayout'a ait özelliklere makalenin ilerleyen kısımlarında değineceğiz.
loadingBehavior: Nesnelerin yüklenmesinin nasıl yapılacağı ve bir seferde kaç nesne yükleneceğinin belirlendiği özelliklerdir. randomaccess ve incremental değerleri vardır. RandomAccess değerinde bir sayfada kullanıcının görüntüleyebileceği sayıda nesneyi otomatik olarak yükler. Incremental değerinde ise pagesToLoad özelliğinde belirtildiği kadar sayfayı yükler. automaticalyLoadPages değeri true olduğu sürece kullanıcı sayfa sonlarına geldikçe nesneleri yüklemeye devam eder. Ayrıca istenildiği durumda loadMorePages metodu çağrılarak sayfaların manuel yüklenmesi sağlanabilir.
loadingState: Listview'in yükleme aşamasında mı olduğu yoksa yüklemenin bittiği mi bilgisini tutar.
pagesToLoad: loadingBehavior'da incremental seçildiği durumda kaç sayfanın yükleneceğinin belirlendiği özelliktir.
selection: ListView'in seçilmiş olan nesnelerinin saklandığı özelliktir.
selectionMode: ListView'in üzerinde kaç nesne seçilebileceğine ait özelliktir. Değerleri none, single, multi olabilir.
swipeBehavior: Listview'in swipe dokunmatik etkileşimine nasıl tepki vereceği belirlenir. Seçenekler none veya select'tir. Select seçili ise kullanıcı swipe ettiği nesneleri seçer.
tapBehavior: Kullanıcı ListView'da bulunan bir nesneye tıkladığında nasıl bir aksiyon gerçekleşeceğini belirler. Seçenekler directSelect, toggleSelect, invokeOnly veya none'dır. DirectSelect'te kullanıcı nesneyi seçer, ToggleSelect'te ise nesnenin seçim modunu değiştirir. InvokeOnly'de ise kullanıcı bir seçim işlemi yapmaz ama itemInvoked metodu fırlatılır. None seçiminde herhangi bir işlem yapılmaz.

Şimdi isterseniz Gridlayout nesnesinin özelliklerini inceleyelim:
groupHeaderPosition: Grup başlıklarının nasıl konumlandırılacağını belirler. Değerler left veya top olabilir.
horizontal: ListView içeriisndeki nesnelerin yatay mı, dikey mi sıralacağının belirlendiği özelliktir. Yatay için true, dikey için false değerleri kullanılır.
maxRows: En fazla kaç satır gösterileceğinin belirlendiği özelliktir.

ListLayout nesnesinin ise sadece horizontal özelliği vardır ve GridLayout nesnesinin horizontal özelliği ile aynı görevi görmektedir.

Şimdi isterseniz Listview üzerinde bazı özellikleri değiştirerek bu özelliklerin ne şekilde kullanıldığını inceleyelim. Bunun için bu özellikleri dinamik değiştirdiğimiz bir uygulama yapıyoruz.

HTML

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>ListView</title>

    <!-- WinJS references -->
    <link href="//Microsoft.WinJS.1.0.RC/css/ui-dark.css" rel="stylesheet" />
    <script src="//Microsoft.WinJS.1.0.RC/js/base.js"></script>
    <script src="//Microsoft.WinJS.1.0.RC/js/ui.js"></script>

    <!-- ListView references -->
    <link href="/css/default.css" rel="stylesheet" />
    <script src="/js/default.js"></script>
</head>
<body>

    <div id="template1" data-win-control="WinJS.Binding.Template">
        <div style="margin: 5px">
            <img data-win-bind="src: image" style="width: 50px; height: 50px; text-align: center" />
            <div data-win-bind="innerText: name" style="text-align: left"></div>
        </div>
    </div>
    <div id="template2" data-win-control="WinJS.Binding.Template">
        <div style="margin: 5px">
            <div data-win-bind="innerText: name" style="text-align: left"></div>
        </div>
    </div>
    <label>Layout : </label>
    <select id="layoutType">
        <option value="WinJS.UI.ListLayout" label="ListLayout"></option>
        <option value="WinJS.UI.GridLayout" label="GridLayout"></option>
    </select>
    <label>
        Selection Mode :
    </label>
    <select id="selectionMode">

        <option value="single" label="Single"></option>
        <option value="multi" label="Multi"></option>
        <option value="none" label="None"></option>
    </select>
    <label>
        Tap Behavior :
    </label>
    <select id="tapBehavior">
        <option value="none" label="None"></option>
        <option value="directSelect" label="DirectSelect"></option>
        <option value="toggleSelect" label="ToggleSelect"></option>
        <option value="invokeOnly" label="InvokeOnly"></option>

    </select>
    <label>
        Template :
    </label>
    <select id="template">
        <option value="template1" label="Resimli"></option>
        <option value="template2" label="Resimsiz"></option>

    </select>
    <br />

    <div id="userListView" data-win-control="WinJS.UI.ListView" data-win-options="{itemTemplate:select('#template1')}"></div>
    <br /><br />
    <label>Aksiyonlar : </label>
    <input type="button" id="btnCurrentItem" value="Aktif Nesne"/>
    <input type="button" id="btnIndexOfFirstVisible" value="İlk Görünen Nesne"/>
    <input type="button" id="btnIndexOfLastVisible" value="Son Görünen Nesne"/>
    <input type="button" id="btnSelectedItems" value="Seçili Nesneler"/>
    <br /><br />
    <div id="log"></div>

</body>
</html>

JavaScript

// For an introduction to the Blank template, see the following documentation:
// http://go.microsoft.com/fwlink/?LinkId=232509
(function () {
    "use strict";

    var app = WinJS.Application;
    var activation = Windows.ApplicationModel.Activation;
    WinJS.strictProcessing();

    app.onactivated = function (args) {
        if (args.detail.kind === activation.ActivationKind.launch) {
            if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                // TODO: This application has been newly launched. Initialize
                // your application here.
            } else {
                // TODO: This application has been reactivated from suspension.
                // Restore application state here.
            }
            args.setPromise(WinJS.UI.processAll());
            loaded();
        }
    };
    function loaded() {
        var usersArray = [
            { image: '/images/user/1.jpg', name: 'Ayşe1' },
            { image: '/images/user/2.jpg', name: 'Ali1' },
            { image: '/images/user/3.jpg', name: 'Ahmet1' },
            { image: '/images/user/4.png', name: 'Mehmet1' },
            { image: '/images/user/5.png', name: 'Mustafa1' },
             { image: '/images/user/1.jpg', name: 'Ayşe2' },
            { image: '/images/user/2.jpg', name: 'Ali2' },
            { image: '/images/user/3.jpg', name: 'Ahmet2' },
            { image: '/images/user/4.png', name: 'Mehmet2' },
            { image: '/images/user/5.png', name: 'Mustafa2' },
        ]

        var dataList = new WinJS.Binding.List(usersArray);

        var lst = document.getElementById('userListView').winControl;
        lst.itemDataSource = dataList.dataSource;

        layoutType.addEventListener('change', function () {
            SetListLayoutType(lst)
        });
        selectionMode.addEventListener('change', function () {
            lst.selectionMode = selectionMode.value;
        });
        tapBehavior.addEventListener('change', function () {
            lst.tapBehavior = tapBehavior.value;
        });
        template.addEventListener('change', function () {
            lst.itemTemplate = document.getElementById(template.value);
        });

        btnCurrentItem.addEventListener('click', function () {
            var key = lst.currentItem.key;
            PrintToLog('Aktif Nesne Adı : ' + dataList.getItemFromKey(key).data.name);
        });

        btnIndexOfFirstVisible.addEventListener('click', function () {
            var index = lst.indexOfFirstVisible;
            PrintToLog('İlk Gözüken Nesne Adı : ' + dataList.getItem(index).data.name);
        });

        btnIndexOfLastVisible.addEventListener('click', function () {
            var index = lst.indexOfLastVisible;
            PrintToLog('Son Gözüken Nesne Adı : ' + dataList.getItem(index).data.name);
        });

        btnSelectedItems.addEventListener('click', function () {
            lst.selection.getItems().then(function (items) {
                var selected = '';
                for (var i = 0; i < items.length ; i++) {
                    selected += items[i].data.name + ', ';
                }
                PrintToLog('Seçili Nesneler : ' + selected);
            });

        });

        lst.addEventListener('iteminvoked', function (e) {
            PrintToLog('Nesne Invoke Oldu : ' + dataList.getItem(e.detail.itemIndex).data.name);
        });

        lst.addEventListener('loadingstatechanged', function (e) {
            PrintToLog('ListView Durumu : ' + lst.loadingState);
        });

        lst.addEventListener('selectionchanged', function (e) {
            PrintToLog('ListView seçim değişti');
        });

        SetList(lst);
    }
    function PrintToLog(s) {
        log.innerHTML = s + '<br>' + log.innerHTML;
    }
    function SetList(lst) {
        SetListLayoutType(lst);
        lst.selectionMode = 'single';
        lst.tapBehavior = 'none';
        lst.itemTemplate = document.getElementById('template1');

    }
    function SetListLayoutType(lst) {
        if (layoutType.value == 'WinJS.UI.ListLayout') {
            lst.layout = new WinJS.UI.ListLayout();
        }
        else {
            lst.layout = new WinJS.UI.GridLayout();
        }
    }

    app.oncheckpoint = function (args) {
        // TODO: This application is about to be suspended. Save any state
        // that needs to persist across suspensions here. You might use the
        // WinJS.Application.sessionState object, which is automatically
        // saved and restored across suspension. If you need to complete an
        // asynchronous operation before your application is suspended, call
        // args.setPromise().
    };

    app.start();
})();

Ve ekran görüntüsü aşağıdaki gibi oluyor:



 

Örnek Kodlar