How do you get a MergedDictionary xamarin forms? - xamarin.forms

Hi I need to modify at runtime a mergedDictionary.
I have
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<themes:LightTheme />
<themes:DarkTheme />
<globalStyles:Labels />
<globalStyles:Controls />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
App.Xaml (I tried the following but always get null) but In debug I can see those dictionaries ..
1. Application.Current.Resources.TryGetValue("LightTheme", out var lightTheme);
2. var theStyle= Xamarin.Forms.Application.Current.Resources.MergedDictionaries.SingleOrDefault(x => x.ContainsKey("DarkTheme"));
What Am I missing?
Thanks

Just found out how to do this
Application.Current.Resources.MergedDictionaries.OfType().FirstOrDefault();

Related

Autofac Dependency Resolution Exception

When I use a LinearGradientBrush (from the new 4.8 version of Xamarin.Forms), I get the followin error:
Autofac.Core.DependencyResolutionException: 'An exception was thrown while activating App.Modules.Loading.LoadingView.'
In the page preview in Visual Studio, it shows the page as expected. When I comment the LinearGradientBrush block, it runs fine.
Do you have any idea why this happens?
Thank you!
Best regards,
Eduardo Luczinski.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="App.Modules.Loading.LoadingView">
<ContentPage.Background>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<GradientStop Color="#3B8476"
Offset="0.1"/>
<GradientStop Color="#00352B"
Offset="1.0"/>
</LinearGradientBrush>
</ContentPage.Background>
<ContentPage.Content>
<StackLayout VerticalOptions="End" HorizontalOptions="FillAndExpand">
<ProgressBar x:Name="loadingBar" VerticalOptions="End" ProgressColor="#FFFF" Progress="0.25"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
If you want to enable LinearGradientBrush in ContentPage, according to this document,you need to set up experimental flags in your target platforms projects.
On android in your MainActivity class, on ios in AppDelegate Class:
Forms.SetFlags("Brush_Experimental");
Making sure to call SetFlags() before Xamarin.Forms.Forms.Init()
The there is no problem, and it works fine.

How to provide BindingContext to Control template

I have a template defined in App.Xaml
<ResourceDictionary>
<ControlTemplate x:Key="HomePageTemplate">
<Label Text="{Binding MyLabelText}"/>
</ControlTemplate>
</ResourceDictionary>
And I use it in my Home page
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:cv="clr-namespace:Xamarin.Forms;assembly=Xamarin.Forms.CarouselView"
xmlns:local="clr-namespace:App.Converters"
x:Class="App.Views.HomePage"
ControlTemplate="{StaticResource HomePageTemplate}">
</ContentPage>
I set the BindingContext of my Homepage in code behind.
Now shouldn't the ControlTemplate inherit the HomePage's BindingContext ? Because I thought that was the case but my Label doesn't keep the text from MyLabelText. What's the work around to work with Bindings in these templates ?
EDIT:
Using this option
<ResourceDictionary>
<ControlTemplate x:Key="HomePageTemplate">
<Label Text="{TemplateBinding Parent.BindingContext.MyLabelText}"/>
</ControlTemplate>
</ResourceDictionary>
Also does not work for me, because I use the ControlTemplatein the header of the HomePage and not inside it's body.
This works BUT IT'S NOT what I'm looking for:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:cv="clr-namespace:Xamarin.Forms;assembly=Xamarin.Forms.CarouselView"
xmlns:local="clr-namespace:App.Converters"
x:Class="App.Views.HomePage"
>
<ContentView ControlTemplate="{StaticResource HomePageTemplate}" />
</ContentPage>
With ControlTemplate controls the binding is slightly different. Have a look at these docs: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/templates/control-templates/template-binding
Assuming that the MyLabelText property is part of the BindingContext of the parent control your code could look like this:
<ResourceDictionary>
<ControlTemplate x:Key="HomePageTemplate">
<Label Text="{TemplateBinding Parent.BindingContext.MyLabelText }"/>
</ControlTemplate>
</ResourceDictionary>
App.xaml should have a BindingContext. Let's call it AppViewmodel, with a namespace vm (or any other key) defined at the top of App.xaml. This AppViewmodel can be bound to from within the ControlTemplate. In this example a button (placed in a stacklayout) is bound to a command named AppCommand, which resides in AppViewmodel. When this ControlTemplate is applied in a ContentPage, it binds to the ViewModel of App.xaml, not to the VM of that particular ContentPage. Perhaps the latter is also possible, for example by choosing the right settings for RelativeSource and AncestorType, but I haven't figured that out.
see also
<ControlTemplate x:Key="HomePageTemplate">
<StackLayout BindingContext="{Binding Source={RelativeSource TemplatedParent}}">
<Button
Command="{Binding Source={RelativeSource AncestorType={x:Type vm:AppViewModel}}, Path=AppCommand}"
/>
</StackLayout>
</ControlTemplate>
If anyone its interested, the way this works its just adding Path after TemplateBinding, specifying BindingContext on it and then the public var name:
<ResourceDictionary>
<ControlTemplate x:Key="HomePageTemplate">
<Label Text="{ TemplateBinding Path=BindingContext.MyLabelText }"/>
</ControlTemplate>
</ResourceDictionary>

XFGloss: How to define as global style in App.xaml

I want to each content page contain the following element
<xfg:ContentPageGloss.BackgroundGradient>
<xfg:Gradient Rotation="170">
<xfg:GradientStep StepColor="#9DCC5F" StepPercentage="0" />
<xfg:GradientStep StepColor="#00B0CD" StepPercentage="1" />
</xfg:Gradient>
</xfg:ContentPageGloss.BackgroundGradient>
How can I do?
Why not create an overload of the ContentPage?
Create a file, for instance, GlossContentPage.
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:xfg="clr-namespace:XFGloss;assembly=XFGloss"
x:Class="YourApp.Pages.GlossContentPage">
<xfg:ContentPageGloss.BackgroundGradient>
<xfg:Gradient Rotation="170">
<xfg:GradientStep StepColor="#9DCC5F" StepPercentage="0" />
<xfg:GradientStep StepColor="#00B0CD" StepPercentage="1" />
</xfg:Gradient>
</xfg:ContentPageGloss.BackgroundGradient>
</ContentPage>
Now just start using your new GlossContentPage, instead of a regular ContentPage, like:
<pages:GlossContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:pages="clr-namespace:YourApp.Pages;assembly=YourApp"
x:Class="YourApp.Pages.MyNewShinyPage">
<Label Text="Welcome to Xamarin.Forms" HorizontalOptions="Center" VerticalOptions="Center" />
</pages:GlossContentPage>

Find a view for a ContentControl in a ResourceDictionary

I'm trying to make Caliburn Micro find my view, which is located in a ResourceDictionary, to be used in a ContentControl.
<Window x:Class="RSA.UI.Prosit.Sales.Views.GenericPrositDialog"
<!-- ... -->>
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="PolicyOverview/PolicyOverviewDialogs.xaml"/>
<!-- ... -->
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid MaxHeight="{Binding MaxWindowHeight}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ContentControl Content="{Binding}"></ContentControl>
</Grid>
</Window>
In PolicyOverviewDialogs.xaml I have
<DataTemplate DataType="{x:Type vm:NotesViewModel}">
...
How can I get Caliburn Micro's WindowManager to find the view?
Trying things like
_windowManager.ShowDialog(notesVM, null, settings);
_windowManager.ShowDialog(notesVM, "GenericPrositDialogView", settings);
but they all come up short with a message "Cannot find view for NotesViewModel". Anyone has experience with this?
Everything works fine if I make the view its' own file "NotesView.xaml", but that's not what I want.

Xamarin.Forms How do we remove a child from a TabbedPage's children?

I would like to add and remove child pages from a tabbed page in certain conditions.
However, it gives me that collection "Children" is read only .
Has anyone succeeded ?
Here is the code for TabbedPage
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
xmlns:partialViews="clr-namespace:TestTabbed.Views.PartialViews;assembly=TestTabbed"
prism:ViewModelLocator.AutowireViewModel="False"
x:Class="TestTabbed.Views.MainPage"
ItemsSource="{Binding ChannelLists}" Appearing="MainPage_OnAppearing"
Disappearing="MainPage_OnDisappearing">
<TabbedPage.ItemTemplate>
<DataTemplate>
<ContentPage Title="{Binding Name}" x:Name="mainContentPage">
<ContentPage.Content>
<OnIdiom x:TypeArguments="View">
<OnIdiom.Phone>
<partialViews:MainPhoneView />
</OnIdiom.Phone>
<OnIdiom.Tablet>
<partialViews:MainTabletView />
</OnIdiom.Tablet>
</OnIdiom>
</ContentPage.Content>
</ContentPage>
</DataTemplate>
</TabbedPage.ItemTemplate>
</TabbedPage>
Seeing your code might be helpful in case I am missing the actual issue but the following should work for you (note that you cannot directly assign a collection to the TabbedPage.Children property which is what it sounds like you are running into):
TabbedPage tab = new TabbedPage();
ContentPage page = new ContentPage();
tab.Children.Add(page);
tab.Children.Remove(page);
Where as the following will not work:
TabbedPage tab = new TabbedPage();
tab.Children = new List<Page>();

Resources