I use SfPopupLayout and PopupView on both iOS and Android. My app supports both light and dark mode. I have a global resource dictionary that declares styles for many view, including the PopupView. One of the global styles is as follows:
<sfpl:PopupStyle x:Key="PopupStyle"
AcceptButtonBackgroundColor="{AppThemeBinding Light={x:StaticResource BackgroundColorLight},
Dark={StaticResource BackgroundColorDark}}"
AcceptButtonTextColor="{AppThemeBinding Light={StaticResource TextColorLight},
Dark={StaticResource TextColorDark}}"
BorderColor="{AppThemeBinding Light={StaticResource BorderColorLight},
Dark={StaticResource BorderColorDark}}"
DeclineButtonBackgroundColor="{AppThemeBinding Light={x:StaticResource BackgroundColorLight},
Dark={StaticResource BackgroundColorDark}}"
DeclineButtonTextColor="{AppThemeBinding Light={StaticResource TextColorLight},
Dark={StaticResource TextColorDark}}"
FooterBackgroundColor="{AppThemeBinding Light={x:StaticResource BackgroundColorLight},
Dark={StaticResource BackgroundColorDark}}"
HeaderBackgroundColor="{AppThemeBinding Light={x:StaticResource BackgroundColorLight},
Dark={StaticResource BackgroundColorDark}}"
HeaderFontFamily="{x:Static font:OpenSans.Semibold}" />
<Style TargetType="sfpl:PopupView">
<Setter Property="PopupStyle" Value="{StaticResource PopupStyle}" />
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={x:StaticResource BackgroundColorLight}, Dark={StaticResource BackgroundColorDark}}" />
</Style>
Now in light mode everything appears as it should be; however, changing the app to dark mode results in a dark dialog with the correct white text, but the accept button background remains white. I have tried explicitly setting the background colors on the view but this did not change anything.
Here is a sample of how I create this PopupView:
<popup:SfPopupLayout AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All"
IsOpen="{Binding IsPopupShowing}"
IsVisible="{Binding IsPopupShowing}">
<popup:SfPopupLayout.PopupView>
<popup:PopupView AcceptButtonText="Ok"
BackgroundColor="{AppThemeBinding Light={x:StaticResource BackgroundColorLight},
Dark={StaticResource BackgroundColorDark}}"
ContentTemplate="{StaticResource PopupContentDataTemplate}"
ShowHeader="False" />
</popup:SfPopupLayout.PopupView>
</popup:SfPopupLayout>
If your view is truly "native", then it should at least be respecting the OS theme. I have selected the system (OS) theme as Dark in this screenshot and your "native" view is disregarding the system theme to display white. I might as well write my own view and ditch this one since its functionality is not consistent with other SyncFusion views. Is there any plan to support AppThemeBinding like your other views, or should I get started writing my own view that can support a basic feature of Xamarin?
|
// Forms class
public class PopupView : View, IDisposable { public static readonly BindableProperty HeaderTitleProperty = BindableProperty.Create("HeaderTitle", typeof(string), typeof(PopupView), "Title", BindingMode.TwoWay, null, propertyChanged: OnHeaderTitlePropertyChanged); private static void OnHeaderTitlePropertyChanged(BindableObject bindable, object oldValue, object newValue) {
SfPopupLayout popuplayout = (bindable as PopupView).SfPopupLayout;
if (popuplayout != null && popuplayout.Content == null && popuplayout.NativeObject != null)
{
DependencyService.Get<IPopupLayoutDependencyService>().MapPopupViewProperties("HeaderTitle", popuplayout);
}
popuplayout = null;
}
} // DependencyClass internal static void MapPopupViewProperties(string propertyName, formsNamespace.PopupView formsPopupView, PopupView nativePopupView) {
if (formsPopupView.SfPopupLayout.NativeObject == null || nativePopupView == null)
{
return;
}
if (propertyName == "AppearanceMode")
{
nativePopupView.AppearanceMode = formsPopupView.AppearanceMode.GetNativeAppearanceMode();
}
else if (propertyName == "ShowHeader")
{
nativePopupView.ShowHeader = formsPopupView.ShowHeader;
}
else if (propertyName == "ShowFooter")
{
nativePopupView.ShowFooter = formsPopupView.ShowFooter;
}
else if (propertyName == "HeaderTitle")
{
nativePopupView.HeaderTitle = formsPopupView.HeaderTitle;
} } // Native Class internal class PopupView : LinearLayout, IDisposable { } |
I'm really not sure what relevancy the header title has to my issue. I've not mentioned issues with the popup view header anywhere. Please refer to my original message images, where you can see the footer is incorrectly colored.
A binding is a binding. Since you're using bindable properties, conformance to the AppThemeBindingExtension should be completely free since the binding engine does all the heavy lifting for you and all you need to do is set the background color of the view on the property change event or during a draw call to your renderer.
It's unfortunate as paying customers to have to deal with this kind of inconsistent behavior where parts of your library support app theme bindings and parts of it don't for completely arbitrary reasons. We're trying to release dark mode support for our app and this is a blocking issue.
|
// Forms class
public class PopupView : View, IDisposable
{ public static readonly BindableProperty PopupStyleProperty =
BindableProperty.Create("PopupStyle", typeof(PopupStyle), typeof(PopupView), null, BindingMode.TwoWay, null, propertyChanged: OnPopupStylePropertyChanged);
private static void OnPopupStylePropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
SfPopupLayout popuplayout = (bindable as PopupView).SfPopupLayout;
if (popuplayout != null && popuplayout.Content == null && popuplayout.NativeObject != null)
{
DependencyService.Get<IPopupLayoutDependencyService>().MapPopupViewProperties("PopupStyle", popuplayout);
}
popuplayout = null;
}
} // DependencyClass internal static void MapPopupViewProperties(string propertyName, formsNamespace.PopupView formsPopupView, PopupView nativePopupView) {
if (formsPopupView.SfPopupLayout.NativeObject == null || nativePopupView == null)
{
return;
}
if (propertyName == "AppearanceMode")
{
nativePopupView.AppearanceMode = formsPopupView.AppearanceMode.GetNativeAppearanceMode();
}
else if (propertyName == "ShowHeader")
{
nativePopupView.ShowHeader = formsPopupView.ShowHeader;
}
else if (propertyName == "ShowFooter")
{
nativePopupView.ShowFooter = formsPopupView.ShowFooter;
}
else if (propertyName == "PopupStyle")
{
nativePopupView.PopupStyle = formsPopupView.PopupStyle;
}
…
}
// Native Class internal class PopupView : LinearLayout, IDisposable { } |
Please correct me if I'm wrong but it sounds like what you're saying is it's impossible to change the background color even though you provide bindable properties to set the background colors. This is very frustrating and confusing behavior.
|
<ContentPage.Resources>
<Color x:Key="BackgroundColorLight">Yellow</Color>
<Color x:Key="BackgroundColorDark">Pink</Color>
</ContentPage.Resources>
<sfPopup:SfPopupLayout x:Name="popupLayout">
<sfPopup:SfPopupLayout.PopupView>
<sfPopup:PopupView >
<sfPopup:PopupView.PopupStyle>
<sfPopup:PopupStyle
HeaderFontAttribute="Bold"
AcceptButtonBackgroundColor="{AppThemeBinding Light={x:StaticResource BackgroundColorLight},Dark={x:StaticResource BackgroundColorDark},Default=Green}"
HeaderFontSize="25"
HeaderTextAlignment="Center"
/>
</sfPopup:PopupView.PopupStyle>
</sfPopup:PopupView>
</sfPopup:SfPopupLayout.PopupView>
|