locked
How to add resources to custom xaml ViewCell RRS feed

  • Question

  • User13169 posted

    Hi all. As you know in xaml for each content page you can specify it's resource dictionary and use them like this

        <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="MyClass"
                     xmlns:local="clr-namespace:MyProject.Forms;assembly=MyProject">
            <ContentPage.Resources>
                <ResourceDictionary>
                     <local:InverseBoolConverter x:Key="inverse" />
                     <local:BoolToOpacityConverter x:Key="opacity" />
                     <local:InverseBoolToOpacityConverter x:Key="inverseOpacity" />
                </ResourceDictionary>
             </ContentPage.Resources>
            <ContentPage.Content>
                <StackLayout Padding="0,20,0,5" IsVisible="{Binding IsNetworkAvailable, Converter={StaticResource inverse}}">
                    ......
                </StackLayout>
            </ContentPage.Content>
        </ContentPage>
    

    I'm also used to create ListView cell templates in separate xaml file to reuse them in different xaml pages. However I didn't find a way to use ResourceDictionary in my custom ViewCell xaml. I tried something like this

    <ViewCell
        xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        x:Class="MyListCell"
        xmlns:local="clr-namespace:MyProject;assembly=MyProject">
        <ViewCell.Resources>
            <ResourceDictionary>
                     <local:BoolToOpacityConverter x:Key="opacity" />
                     <local:InverseBoolToOpacityConverter x:Key="inverseOpacity" />
             </ResourceDictionary> 
        </ViewCell.Resources>
    </ViewCell>
    

    However I get runtime exception that ViewCell doesn't have Resources property. Anyone knows how to achieve this? My pain purpose is being able to use converters in custom ViewCell xaml, and perhaps there is other way of doing that. Please don't comment that you can use custom property on BindingContext and place the converted data into that property instead of using converter, I know that. But I don't want to create custom property when the best practice in MVVM is creating converter. Any ideas?

    Wednesday, September 30, 2015 6:01 AM

All replies

  • User41011 posted

    I'm also interested if someone has an answer :)

    Wednesday, September 30, 2015 12:36 PM
  • User13169 posted

    I've figured this out! What I did I've tried to find the base class for ContentPage which declares Resources dictionary property, and I've found that! It was VisualElement. If you look into ViewCell documentation it inherits from Cell class, which inherits from Element class not VisualElement. Perhaps the the ViewCell is not VisualElement because of performance reasons, I don't know. Anyhow, it doesn't take a genius to understand that for the solution of this problem we need a subclass of VisualElement somewhere inside ViewCell. For instance StackLayout can work for this purpose, I've tried and IT WORKED :) Here is a sample code.

    <?xml version="1.0" encoding="UTF-8"?>
    <ViewCell
        xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        x:Class="MyApp.Forms.ProductListCell"
        xmlns:local="clr-namespace:MyApp.Forms;assembly=MyApp.Forms"
        xmlns:core="clr-namespace:MyApp.Core;assembly=MyApp.Forms">
        <ViewCell.BindingContext>
            <local:UrlToCachedImageSourceConverter
                x:Key="cachedImage" />
        </ViewCell.BindingContext>
        <StackLayout
            BackgroundColor="Transparent"
            Padding="10,5,10,0">
            <StackLayout
                BackgroundColor="{x:Static local:Colors.UltraLightGray}"
                Orientation="Horizontal">
                <StackLayout.Resources>
                    <ResourceDictionary>
                        <local:UrlToCachedImageSourceConverter
                            x:Key="cachedImage" />
                    </ResourceDictionary>
                </StackLayout.Resources>
                <Image
                    x:Name="Image"
                    Aspect="AspectFill"
                    WidthRequest="95"
                    HeightRequest="95"
                    VerticalOptions="Start"
                    BackgroundColor="Transparent"
                    Source="{Binding ImageUrl, Converter={StaticResource cachedImage}}" />
                <StackLayout
                    Orientation="Vertical"
                    BackgroundColor="Transparent"
                    HorizontalOptions="FillAndExpand"
                    VerticalOptions="Fill"
                    Padding="0,5,5,5">
                    <Label
                        x:Name="NameLabel"
                        Text="{Binding Name}"
                        TextColor="{x:Static local:Colors.Black}"
                        FontAttributes="Bold" />
                    <Label
                        x:Name="PriceLabel"
                        Text="{Binding FormattedPrice}"
                        XAlign="End"
                        TextColor="{x:Static local:Colors.DarkGray}"
                        VerticalOptions="End"
                        HorizontalOptions="End" />
                </StackLayout>
            </StackLayout>
        </StackLayout>
    </ViewCell>
    
    Friday, October 9, 2015 5:57 PM
  • User134191 posted

    This is a neat trick! Nice work.

    Friday, November 20, 2015 12:08 AM