简体   繁体   中英

Using ResourceDictionary.MergedDictionaries in App.xaml

In VS2017 with Xamarin

In my app.xaml I have a MergedDictionary which references a xaml containing my DataTemplate. It isn't being recognized by a content page. If I move the DataTemplate into the app.xaml it works fine.

How do I get the <ResourceDictionary.MergedDictionaries> to recognize the StaticResource defined in the CellTemplates.xaml ?

My App.xaml:

<Application.Resources>
   <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Resources/CellTemplates.xaml"/>
        </ResourceDictionary.MergedDictionaries>
   ....

My CellTemplates.xaml:

 <ResourceDictionary
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <DataTemplate x:Key="CustomerTemplate">
    <ViewCell Height="100">
          <StackLayout VerticalOptions="FillAndExpand">
     ....

My Content Page:

<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:local="clr-namespace:Muffin"
         x:Class="Muffin.MainPage">
<ScrollView>
    <ListView ItemsSource="{Binding Customers}" 
              HasUnevenRows="True" 
              ItemTemplate="{StaticResource CustomerTemplate}">
    </ListView>
....

It's possible to create custom ResourceDictionary with multiple merging support.

See: https://github.com/Makeloft/Ace/blob/master/Ace.Zest/Markup/ResourceDictionary.cs

internal static class MergeExtensions
{
    internal static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
    {
        foreach (var item in items) action(item);
    }

    internal static void Merge<TKey, TValue>(this IDictionary<TKey, TValue> targetDictionary,
        IEnumerable<KeyValuePair<TKey, TValue>> sourceItems)
    {
        var targetItems = targetDictionary.ToArray();
        sourceItems.ForEach(i => targetDictionary[i.Key] = i.Value);
        targetItems.ForEach(i => targetDictionary[i.Key] = i.Value); // override merged by local values
    }
}

public class ResourceDictionary : Xamarin.Forms.ResourceDictionary
{
    public ResourceDictionary()
    {
        MergedDictionaries = new ObservableCollection<Xamarin.Forms.ResourceDictionary>();
        MergedDictionaries.CollectionChanged += (sender, args) =>
            (args.NewItems ?? new List<object>()).OfType<Xamarin.Forms.ResourceDictionary>()
            .ForEach(this.Merge);
    }

    public ObservableCollection<Xamarin.Forms.ResourceDictionary> MergedDictionaries { get; }
}

Usage

<Application.Resources>
    <m:ResourceDictionary>
        <m:ResourceDictionary.MergedDictionaries>
            <local:AppConverters />
        </m:ResourceDictionary.MergedDictionaries>

        <AnotherResource x:Key="Key1" />
    </m:ResourceDictionary>
</Application.Resources>

You are trying to use a functionality that is not currently available in Xamarin.Forms and that's the use of multiple Merged Dictionaries. At the moment you can only have a single MergedDictionary

Try this in your code:

App.xaml

<?xml version="1.0" encoding="utf-8"?>
<Application xmlns="http://xamarin.com/schemas/2014/forms" 
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    xmlns:local="clr-namespace:Muffin"
    x:Class="Muffin.App">
    <Application.Resources>
        <ResourceDictionary MergedWith="local:CellTemplates">
                  ...
            <!--YOUR APP LEVEL STYLES -->
                  ...
        </ResourceDictionary>
    </Application.Resources>
</Application>

Note that to merge the Resource is not used the physical file location instead it's used the full namespace + class name.

Good news is that the possibility of merging more than one ResourceDictionary in Xamarin is under development and it should be available any soon. If you want to follow the advances of this feature subscribe to this thread in github.

Hope this helps.-

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM