Reputation: 68750
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>
....
Upvotes: 6
Views: 3077
Reputation: 944
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>
Upvotes: 3
Reputation: 9346
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.-
Upvotes: 2