içinde Bağlanabilir Düzenler Xamarin.Forms

Download Sample Örneği indirme

Bağlanabilir düzenler, sınıfından Layout<T> türetilen tüm düzen sınıflarının bir öğe koleksiyonuna bağlayarak içeriğini oluşturmasına olanak tanır ve her öğenin görünümünü bir DataTemplateile ayarlama seçeneğiyle sağlar. Bağlanabilir düzenler, aşağıdaki ekli özellikleri kullanıma sunan sınıfı tarafından BindableLayout sağlanır:

  • ItemsSource – düzen tarafından görüntülenecek öğe koleksiyonunu IEnumerable belirtir.
  • ItemTemplate – düzeni tarafından görüntülenen öğe koleksiyonundaki her öğeye uygulanacak öğesini belirtir DataTemplate .
  • ItemTemplateSelector– çalışma zamanında bir öğe için seçim DataTemplate yapmak için kullanılacak olanı belirtirDataTemplateSelector.

Not

ItemTemplate hem hem ItemTemplateSelector de ItemTemplate özellikleri ayarlandığında özelliği önceliklidir.

Buna ek olarak, BindableLayout sınıfı aşağıdaki bağlanabilir özellikleri kullanıma sunar:

  • EmptyView– özelliği olduğunda ItemsSource veya özelliği nulltarafından nullItemsSource belirtilen koleksiyon boş olduğunda görüntülenecek veya görünümünü belirtirstring. Varsayılan değer şudur: null.
  • EmptyViewTemplate– özelliği olduğunda ItemsSource veya özelliği nulltarafından belirtilen koleksiyon boş olduğunda görüntülenecek olan öğesini ItemsSourcenull belirtirDataTemplate. Varsayılan değer şudur: null.

Not

EmptyViewTemplate hem hem EmptyViewTemplate de EmptyView özellikleri ayarlandığında özelliği önceliklidir.

Bu özelliklerin tümü, sınıfından AbsoluteLayouttüretilen , FlexLayoutGrid, , RelativeLayoutve StackLayout sınıflarına Layout<T> eklenebilir.

Layout<T> sınıfı, bir Children düzenin alt öğelerinin eklendiği bir koleksiyonu kullanıma sunar. BindableLayout.ItemsSource özelliği bir öğe koleksiyonuna ayarlandığında ve -derived sınıfına Layout<T>eklendiğinde, koleksiyondaki her öğe düzen tarafından görüntülenmek üzere koleksiyona Layout<T>.Children eklenir. Temel Layout<T>alınan koleksiyon değiştiğinde -derived sınıfı alt görünümlerini güncelleştirir. Düzen döngüsü hakkında Xamarin.Forms daha fazla bilgi için bkz . Özel Düzen Oluşturma.

Bağlanabilir düzenler yalnızca görüntülenecek öğe koleksiyonu küçük olduğunda ve kaydırma ve seçim gerekli olmadığında kullanılmalıdır. Kaydırma, içinde bağlanabilir bir düzeni ScrollViewsarmalayarak sağlanabilir, ancak bağlanabilir düzenlerde kullanıcı arabirimi sanallaştırması olmadığından bu önerilmez. Kaydırma gerektiğinde veya CollectionViewgibi ListView kullanıcı arabirimi sanallaştırması içeren kaydırılabilir bir görünüm kullanılmalıdır. Bu önerinin gözlemlenmemesi performans sorunlarına yol açabilir.

Önemli

Teknik olarak, sınıfından türetilen Layout<T> herhangi bir düzen sınıfına bağlanabilir bir düzen eklemek mümkün olsa da, özellikle , Gridve RelativeLayout sınıfları için AbsoluteLayoutbunu yapmak her zaman pratik değildir. Örneğin, bir veri koleksiyonunu, koleksiyondaki her öğenin birden çok özellik içeren bir Grid nesne olduğu, bağlanabilir bir düzen kullanarak bir veri koleksiyonu görüntülemek isteme senaryoyu düşünün. içindeki Grid her satır, koleksiyondan bir nesne görüntülemeli ve her sütun nesnenin Grid özelliklerinden birini görüntülemelidir. DataTemplate bağlanabilir düzen için yalnızca tek bir nesne içerebileceğinden, bu nesnenin her birinin nesnenin özelliklerinden birini belirli Grid bir sütunda görüntüleyen birden çok görünüm içeren bir düzen sınıfı olması gerekir. Bu senaryo, bağlanabilir düzenlerle gerçekleştirilebilir olsa da, ilişkili koleksiyondaki her öğe için bir üst Grid öğe içeren bir üst Grid öğeyle sonuçlanır ve bu da düzenin Grid son derece verimsiz ve sorunlu bir kullanımıdır.

Bağlanabilir düzeni verilerle doldurma

Bağlanabilir düzen, özelliğini uygulayan IEnumerableherhangi bir koleksiyona ayarlayarak ItemsSource ve bunu türetilmiş bir Layout<T>sınıfa ekleyerek verilerle doldurulur:

<Grid BindableLayout.ItemsSource="{Binding Items}" />

Eşdeğer C# kodu:

IEnumerable<string> items = ...;
var grid = new Grid();
BindableLayout.SetItemsSource(grid, items);

BindableLayout.ItemsSource Ekli özellik bir düzende ayarlandığında, ancak BindableLayout.ItemTemplate ekli özellik ayarlanmamışsa, koleksiyondaki IEnumerable her öğe sınıfı tarafından BindableLayout oluşturulan bir Label tarafından görüntülenir.

Öğe görünümünü tanımlama

Bağlanabilir düzendeki her öğenin görünümü, iliştirilmiş özelliği olarak DataTemplateayarlanarak BindableLayout.ItemTemplate tanımlanabilir:

<StackLayout BindableLayout.ItemsSource="{Binding User.TopFollowers}"
             Orientation="Horizontal"
             ...>
    <BindableLayout.ItemTemplate>
        <DataTemplate>
            <controls:CircleImage Source="{Binding}"
                                  Aspect="AspectFill"
                                  WidthRequest="44"
                                  HeightRequest="44"
                                  ... />
        </DataTemplate>
    </BindableLayout.ItemTemplate>
</StackLayout>

Eşdeğer C# kodu:

DataTemplate circleImageTemplate = ...;
var stackLayout = new StackLayout();
BindableLayout.SetItemsSource(stackLayout, viewModel.User.TopFollowers);
BindableLayout.SetItemTemplate(stackLayout, circleImageTemplate);

Bu örnekte, koleksiyondaki TopFollowers her öğe içinde DataTemplatetanımlanan bir CircleImage görünümle görüntülenir:

Bindable layout with a DataTemplate

Veri şablonları hakkında daha fazla bilgi için bkz Xamarin.Forms . Veri Şablonları.

Çalışma zamanında öğe görünümünü seçme

Bağlanabilir düzendeki her öğenin görünümü, öğe değerine göre çalışma zamanında ekli özelliği olarak DataTemplateSelectorayarlanarak BindableLayout.ItemTemplateSelector seçilebilir:

<FlexLayout BindableLayout.ItemsSource="{Binding User.FavoriteTech}"
            BindableLayout.ItemTemplateSelector="{StaticResource TechItemTemplateSelector}"
            ... />

Eşdeğer C# kodu:

DataTemplateSelector dataTemplateSelector = new TechItemTemplateSelector { ... };
var flexLayout = new FlexLayout();
BindableLayout.SetItemsSource(flexLayout, viewModel.User.FavoriteTech);
BindableLayout.SetItemTemplateSelector(flexLayout, dataTemplateSelector);

DataTemplateSelector Örnek uygulamada kullanılan aşağıdaki örnekte gösterilmiştir:

public class TechItemTemplateSelector : DataTemplateSelector
{
    public DataTemplate DefaultTemplate { get; set; }
    public DataTemplate XamarinFormsTemplate { get; set; }

    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
    {
        return (string)item == "Xamarin.Forms" ? XamarinFormsTemplate : DefaultTemplate;
    }
}

TechItemTemplateSelector sınıfı, farklı veri şablonlarına ayarlanmış ve XamarinFormsTemplateDataTemplate özelliklerini tanımlarDefaultTemplate. OnSelectTemplate yöntemi, öğe "Xamarin.Forms" değerine eşit olduğunda yanında kalp bulunan koyu kırmızı bir öğe görüntüleyen öğesini döndürürXamarinFormsTemplate. Öğe "Xamarin.Forms" değerine eşit olmadığında, OnSelectTemplate yöntemi öğesini döndürür DefaultTemplateve varsayılan olarak öğesinin rengini kullanarak bir Labelöğe görüntüler:

Bindable layout with a DataTemplateSelector

Veri şablonu seçicileri hakkında daha fazla bilgi için bkz. DataTemplateSelector OluşturmaXamarin.Forms.

Veriler kullanılamadığında dize görüntüleme

EmptyView özelliği, özelliği olduğunda veya özelliği nulltarafından belirtilen koleksiyon boş olduğunda ItemsSource tarafından görüntülenecek bir Label dizeye ItemsSourcenull ayarlanabilir. Aşağıdaki XAML bu senaryonun bir örneğini gösterir:

<StackLayout BindableLayout.ItemsSource="{Binding UserWithoutAchievements.Achievements}"
             BindableLayout.EmptyView="No achievements">
    ...
</StackLayout>

Sonuç, veri bağlı koleksiyon olduğunda nullözellik değeri olarak ayarlanan dizenin EmptyView görüntülenmesidir:

Screenshot of a bindable layout string empty view, on iOS and Android

Veriler kullanılamadığında görünümleri görüntüleme

EmptyView özelliği, özelliği olduğunda ItemsSource veya özelliği nulltarafından belirtilen koleksiyon boş olduğunda görüntülenecek bir görünüme ItemsSourcenull ayarlanabilir. Bu tek bir görünüm veya birden çok alt görünüm içeren bir görünüm olabilir. Aşağıdaki XAML örneği, birden çok alt görünüm içeren bir görünüme ayarlanmış özelliği gösterir EmptyView :

<StackLayout BindableLayout.ItemsSource="{Binding UserWithoutAchievements.Achievements}">
    <BindableLayout.EmptyView>
        <StackLayout>
            <Label Text="None."
                   FontAttributes="Italic"
                   FontSize="{StaticResource smallTextSize}" />
            <Label Text="Try harder and return later?"
                   FontAttributes="Italic"
                   FontSize="{StaticResource smallTextSize}" />
        </StackLayout>
    </BindableLayout.EmptyView>
    ...
</StackLayout>

Sonuç, veri bağlama koleksiyonu olduğunda nullStackLayout ve alt görünümlerinin görüntülenmesidir.

Screenshot of a bindable layout empty view with multiple views, on iOS and Android

Benzer şekilde, özelliği olduğunda ItemsSource veya özelliği nulltarafından ItemsSourcenull belirtilen koleksiyon boş olduğunda görüntülenecek bir olarak ayarlanabilirDataTemplate.EmptyViewTemplate tek DataTemplate bir görünüm veya birden çok alt görünüm içeren bir görünüm içerebilir. Buna ek olarak, BindingContext öğesinin EmptyViewTemplate öğesi öğesinden BindingContextBindableLayoutdevralınır. Aşağıdaki XAML örneği, tek bir görünüm içeren bir DataTemplate olarak ayarlanan özelliği gösterirEmptyViewTemplate:

<StackLayout BindableLayout.ItemsSource="{Binding UserWithoutAchievements.Achievements}">
    <BindableLayout.EmptyViewTemplate>
        <DataTemplate>
            <Label Text="{Binding Source={x:Reference usernameLabel}, Path=Text, StringFormat='{0} has no achievements.'}" />
        </DataTemplate>
    </BindableLayout.EmptyViewTemplate>
    ...
</StackLayout>

Sonuç, veri bağlama koleksiyonu olduğunda nullLabel içindeki DataTemplate öğesinin görüntülenmesidir:

Screenshot of a bindable layout empty view template, on iOS and Android

Not

EmptyViewTemplate özelliği aracılığıyla DataTemplateSelectorayarlanamaz.

Çalışma zamanında EmptyView seçme

Veriler kullanılamadığında olarak EmptyView görüntülenecek görünümler, içindeki ResourceDictionarynesneler olarak ContentView tanımlanabilir. Özelliği EmptyView daha sonra çalışma zamanında bazı iş mantığına göre belirli ContentViewbir olarak ayarlanabilir. Aşağıdaki XAML bu senaryonun bir örneğini gösterir:

<ContentPage ...>
    <ContentPage.Resources>
        ...    
        <ContentView x:Key="BasicEmptyView">
            <StackLayout>
                <Label Text="No achievements."
                       FontSize="14" />
            </StackLayout>
        </ContentView>
        <ContentView x:Key="AdvancedEmptyView">
            <StackLayout>
                <Label Text="None."
                       FontAttributes="Italic"
                       FontSize="14" />
                <Label Text="Try harder and return later?"
                       FontAttributes="Italic"
                       FontSize="14" />
            </StackLayout>
        </ContentView>
    </ContentPage.Resources>

    <StackLayout>
        ...
        <Switch Toggled="OnEmptyViewSwitchToggled" />

        <StackLayout x:Name="stackLayout"
                     BindableLayout.ItemsSource="{Binding UserWithoutAchievements.Achievements}">
            ...
        </StackLayout>
    </StackLayout>
</ContentPage>

XAML, sayfa düzeyinde ResourceDictionaryiki ContentView nesne tanımlar ve nesne hangi ContentView nesnenin SwitchEmptyView özellik değeri olarak ayarlandığını denetler. Switch iki durumlu olduğunda, OnEmptyViewSwitchToggled olay işleyicisi yöntemini yürütürToggleEmptyView:

void ToggleEmptyView(bool isToggled)
{
    object view = isToggled ? Resources["BasicEmptyView"] : Resources["AdvancedEmptyView"];
    BindableLayout.SetEmptyView(stackLayout, view);
}

yöntemi, nesnesinin stackLayout özelliğini, özelliğinin değerine göre içinde ResourceDictionarydepolanan iki ContentView nesneden Switch.IsToggled birine ayarlarEmptyView.ToggleEmptyView Ardından, veri bağlama koleksiyonu olduğunda nullContentView özelliği olarak EmptyView ayarlanan nesne görüntülenir:

Screenshot of empty view choice at runtime, on iOS and Android