Reputation: 3004
I wanna bind a value inside a ResourceDictionary which is a Theme.
I followed some tutorial in https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/theming/theming
Here is the code of the ResourceDictionary named Black.xaml:
<?xml version="1.0" encoding="utf-8"?>
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Test.Themes.Black">
<Color x:Key="PrimaryBackground" x:FactoryMethod="FromHex">
<x:Arguments>
<x:String>#101010</x:String>
</x:Arguments>
</Color>
</ResourceDictionary>
Here is the code in 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:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="Test.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Themes/Black.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
And here is the ContentView:
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Test.Views"
xmlns:VM="clr-namespace:Test.ViewModels"
mc:Ignorable="d"
x:Class="Test.Views.MainView">
<ContentView.BindingContext>
<VM:MainViewVM></VM:MainViewVM>
</ContentView.BindingContext>
<ContentView.Content>
<Grid BackgroundColor="">
</Grid>
</ContentView.Content>
</ContentView>
Now I want to bind the BackgroundColor property of the Grid above to the value PrimaryBackground
of the ResourceDictionary.
How can I achieve it? Thank you.
Upvotes: 1
Views: 816
Reputation: 9234
Just use DynamicResource
to set the BackgroundColor
like following code
<Grid BackgroundColor="{DynamicResource PrimaryBackground}">
<Label Text="Face-Palm Monkey"
VerticalOptions="Center"
Margin="15"/>
</Grid>
Here is running sceenshot.
I recommand you set the ResourceDictionary
directly in App.xaml
like following format.
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="MVVMWebView.App">
<Application.Resources>
<ResourceDictionary>
<Color x:Key="PrimaryBackground" x:FactoryMethod="FromHex">
<x:Arguments>
<x:String>#101010</x:String>
</x:Arguments>
</Color>
</ResourceDictionary>
</Application.Resources>
</Application>
If you want to use IValueConverter
,just add the Converter
in the ContentPage.Resources
like follow code. IValueConverter
used Converter
tab, you just use StaticResource
, it does not conflict with DynamicResource
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:DataBindingDemos"
x:Class="DataBindingDemos.EnableButtonsPage"
Title="Enable Buttons">
<ContentPage.Resources>
<ResourceDictionary>
<local:IntToBoolConverter x:Key="intToBool" />
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout Padding="10, 0">
<Button Text="Search"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
IsEnabled="{Binding Source={x:Reference entry1},
Path=Text.Length,
Converter={StaticResource intToBool}}" />
</StackLayout>
</ContentPage>
==========Update==============
I make a convert by your needs. I used Button
to convert day and night. Here is running GIF.
<ContentPage.Resources>
<ResourceDictionary>
<controls:ColorBoolConverter x:Key="intToBool" />
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout>
<Button Text="Submit"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
Command="{Binding ChangeCommand}"
/>
<!-- Place new controls here -->
<Grid BackgroundColor="{Binding IsDark, Converter={StaticResource intToBool}}">
<Label Text="Face-Palm Monkey"
VerticalOptions="Center"
Margin="15"
/>
</Grid>
</StackLayout>
Here is background code about the Layout.
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
this.BindingContext = new MyViewModel();
}
}
Here is Convertor code.
public class ColorBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is bool)
{
if ((Boolean)value)
return Color.FromHex("#101010");
else
return Color.White;
}
return Color.White;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Here is Test MyViewModel.cs
public class MyViewModel: INotifyPropertyChanged
{
public ICommand ChangeCommand { protected set; get; }
bool _isDark = false;
public bool IsDark
{
get
{
return _isDark;
}
set
{
if (_isDark != value)
{
_isDark = value;
OnPropertyChanged("IsDark");
}
}
}
public MyViewModel()
{
ChangeCommand = new Command(() =>
{
IsDark = !IsDark;
});
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Upvotes: 4