NullReferenceException when using global Style
I'm getting a NullReferenceException when using a global Style.
The same does not happen when the Style has a key and it's applied to the Button itself.
This is the Style:
<Style TargetType="{x:Type l:FlexButton}">
<Setter Property="FontSize" Value="16"/>
<Setter Property="BackgroundColor" Value="{DynamicResource Color.Foreground}"/>
<Setter Property="ForegroundColor" Value="{DynamicResource Color.Background.Odd}"/>
<Setter Property="FontFamily" Value="{StaticResource Font.Heavy}"/>
<Setter Property="CornerRadius" Value="10"/>
</Style>
This is the Button:
<l:FlexButton WidthRequest="25" HeightRequest="25" CornerRadius="38" Text="X" FontSize="10" Padding="0" VerticalOptions="Start" HorizontalOptions="End"/>
The Exception happens when executing this code:
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Forms.Build.Tasks.XamlG", "0.0.0.0")]
private void InitializeComponent()
{
global::Xamarin.Forms.Xaml.Extensions.LoadFromXaml(this, typeof(PhotosView));
}
StackTrace:
at Flex.Controls.FlexButton.SetButtonMode()
at Flex.Controls.FlexButton.OnPropertyChanged(String propertyName)
at Xamarin.Forms.BindableObject.SetValueActual(BindableProperty property, BindablePropertyContext context, Object value, Boolean currentlyApplying, SetValueFlags attributes, Boolean silent)
at Xamarin.Forms.BindableObject.SetValueCore(BindableProperty property, Object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes)
at Xamarin.Forms.BindableObject.SetValue(BindableProperty property, Object value, Boolean fromStyle, Boolean checkAccess)
at Xamarin.Forms.Setter.Apply(BindableObject target, Boolean fromStyle)
at Xamarin.Forms.Style.ApplyCore(BindableObject bindable, Style basedOn)
at Xamarin.Forms.Style.Xamarin.Forms.IStyle.Apply(BindableObject bindable)
at Xamarin.Forms.MergedStyle.SetStyle(IStyle implicitStyle, IList`1 classStyles, IStyle style)
at Xamarin.Forms.MergedStyle.OnImplicitStyleChanged()
at Xamarin.Forms.MergedStyle.<RegisterImplicitStyles>b__30_0(BindableObject bindable, Object oldvalue, Object newvalue)
at Xamarin.Forms.BindableObject.SetValueActual(BindableProperty property, BindablePropertyContext context, Object value, Boolean currentlyApplying, SetValueFlags attributes, Boolean silent)
at Xamarin.Forms.BindableObject.SetValueCore(BindableProperty property, Object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes)
at Xamarin.Forms.Element.OnSetDynamicResource(BindableProperty property, String key)
at Xamarin.Forms.BindableObject.SetDynamicResource(BindableProperty property, String key, Boolean fromStyle)
at Xamarin.Forms.MergedStyle.RegisterImplicitStyles()
at Xamarin.Forms.MergedStyle..ctor(Type targetType, BindableObject target)
at Xamarin.Forms.NavigableElement..ctor()
at Xamarin.Forms.VisualElement..ctor()
at Xamarin.Forms.View..ctor()
at Xamarin.Forms.Layout..ctor()
at Flex.Controls.FlexButton..ctor()
at MyApp.View.RegistrationSteps.PhotosView.InitializeComponent()
at MyApp.View.RegistrationSteps.PhotosView..ctor()
at MyApp.ViewModel.SignUpViewModel.Load_Executed()
at Xamarin.Forms.Command.<>c__DisplayClass4_0.<.ctor>b__0(Object o)
at Xamarin.Forms.Command.Execute(Object parameter)
at MyApp.View.SignUp.OnAppearing()
at Xamarin.Forms.Page.SendAppearing()
at Xamarin.Forms.Page.SendAppearing()
at Xamarin.Forms.Platform.UWP.NavigationPageRenderer.OnLoaded(Object sender, RoutedEventArgs args)
Please complete the following information:
- Which version of the FlexButton do you use? 0.9.1
- Which version of Xamarin.Forms do you use? 3.6.0.293080
- Which OS are you talking about? Android and UWP
@NickeManarin Sometime code behind crash beetwen initlized and not yet.
I fixed code below xaml and cs file. You can try this to use global style
XAML ` <ContentView x:Name="this" x:Class="Flex.Controls.FlexButton" xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:extensions="clr-namespace:Flex.Extensions" xmlns:controls="clr-namespace:Flex.Controls">
<controls:GestureFrame
x:Name="Border"
BackgroundColor="{Binding Source={x:Reference this}, Path=BorderColor}"
CornerRadius="{Binding Source={x:Reference this}, Path=CornerRadius}"
Padding="{Binding Source={x:Reference this}, Path=BorderThickness}"
HasShadow="{Binding Source={x:Reference this}, Path=HasShadow}">
<controls:GestureFrame.BorderColor>
<!--- HACK: Temporary Bugfix for Xamarin.Forms 3.0 bug https://github.com/xamarin/Xamarin.Forms/issues/2634 -->
<OnPlatform x:TypeArguments="Color" Default="Transparent">
<!--<On Platform="Android" Value="{Binding Source={x:Reference this}, Path=BorderColor}" />-->
</OnPlatform>
</controls:GestureFrame.BorderColor>
<controls:GestureFrame.GestureRecognizers>
<extensions:TouchGestureRecognizer x:Name="TouchRecognizer" />
</controls:GestureFrame.GestureRecognizers>
<controls:GestureFrame
x:Name="Container"
BackgroundColor="{Binding Source={x:Reference this}, Path=BackgroundColor}"
CornerRadius="{Binding Source={x:Reference this}, Path=InnerCornerRadius}"
Padding="0"
Margin="0"
HasShadow="false">
<controls:GestureFrame.BorderColor>
<!--- HACK: Temporary Bugfix for Xamarin.Forms 3.0 bug https://github.com/xamarin/Xamarin.Forms/issues/2634 -->
<OnPlatform x:TypeArguments="Color" Default="Transparent">
<!--<On Platform="Android" Value="{Binding Source={x:Reference this}, Path=BackgroundColor}" />-->
</OnPlatform>
</controls:GestureFrame.BorderColor>
<AbsoluteLayout>
<FlexLayout
x:Name="ContainerContent"
Margin="{Binding Source={x:Reference this}, Path=Padding}"
Direction="Row"
AlignItems="Center"
JustifyContent="Center">
<FlexLayout.Triggers>
<MultiTrigger TargetType="FlexLayout" >
<MultiTrigger.Conditions>
<BindingCondition Binding="{Binding Source={x:Reference this}, Path=mode}" Value="IconWithText" />
<BindingCondition Binding="{Binding Source={x:Reference this}, Path=IconOrientation}" Value="Top" />
</MultiTrigger.Conditions>
<Setter Property="Direction" Value="Column" />
</MultiTrigger>
<MultiTrigger TargetType="FlexLayout" >
<MultiTrigger.Conditions>
<BindingCondition Binding="{Binding Source={x:Reference this}, Path=mode}" Value="IconWithText" />
<BindingCondition Binding="{Binding Source={x:Reference this}, Path=IconOrientation}" Value="Left" />
</MultiTrigger.Conditions>
<Setter Property="Direction" Value="Row" />
</MultiTrigger>
<MultiTrigger TargetType="FlexLayout" >
<MultiTrigger.Conditions>
<BindingCondition Binding="{Binding Source={x:Reference this}, Path=mode}" Value="IconWithText" />
<BindingCondition Binding="{Binding Source={x:Reference this}, Path=IconOrientation}" Value="Right" />
</MultiTrigger.Conditions>
<Setter Property="Direction" Value="RowReverse" />
</MultiTrigger>
</FlexLayout.Triggers>
<Image
x:Name="ButtonIcon"
Margin="{Binding Source={x:Reference this}, Path=IconPadding}"
Source="{Binding Source={x:Reference this}, Path=Icon}" >
<Image.Triggers>
<DataTrigger TargetType="Image" Binding="{Binding Source={x:Reference this}, Path=mode}" Value="IconOnly">
<Setter Property="Grid.ColumnSpan" Value="2" />
</DataTrigger>
<DataTrigger TargetType="Image" Binding="{Binding Source={x:Reference this}, Path=mode}" Value="IconWithText">
<Setter Property="IsVisible" Value="True" />
</DataTrigger>
<DataTrigger TargetType="Image" Binding="{Binding Source={x:Reference this}, Path=mode}" Value="TextOnly">
<Setter Property="Grid.ColumnSpan" Value="1" />
<Setter Property="IsVisible" Value="False" />
</DataTrigger>
</Image.Triggers>
</Image>
<Label
x:Name="ButtonText"
HorizontalTextAlignment="Center"
MaxLines="{Binding Source={x:Reference this}, Path=MaxLines}"
Text="{Binding Source={x:Reference this}, Path=Text}"
FontSize="{Binding Source={x:Reference this}, Path=FontSize}"
FontAttributes="{Binding Source={x:Reference this}, Path=FontAttributes}"
FontFamily="{Binding Source={x:Reference this}, Path=FontFamily}"
TextColor="{Binding Source={x:Reference this}, Path=ForegroundColor}" >
<Label.Triggers>
<DataTrigger TargetType="Label" Binding="{Binding Source={x:Reference this}, Path=mode}" Value="IconOnly">
<Setter Property="Grid.Column" Value="1" />
<Setter Property="IsVisible" Value="False" />
</DataTrigger>
<DataTrigger TargetType="Label" Binding="{Binding Source={x:Reference this}, Path=mode}" Value="IconWithText">
<Setter Property="Grid.Column" Value="0" />
<Setter Property="Grid.ColumnSpan" Value="1" />
<Setter Property="IsVisible" Value="True" />
</DataTrigger>
<DataTrigger TargetType="Label" Binding="{Binding Source={x:Reference this}, Path=mode}" Value="TextOnly">
<Setter Property="Grid.ColumnSpan" Value="2" />
<Setter Property="Grid.Column" Value="0" />
<Setter Property="IsVisible" Value="True" />
</DataTrigger>
</Label.Triggers>
</Label>
</FlexLayout>
</AbsoluteLayout>
</controls:GestureFrame>
</controls:GestureFrame>
`
Code behind: ` [assembly: XamlCompilation(XamlCompilationOptions.Compile)] namespace Flex.Controls { public partial class FlexButton : ContentView { //ButtonMode mode; bool userChangedPadding; bool userChangedIconPadding;
public void SetChangedPadding(bool val)
{
userChangedPadding = val;
}
public void SetChangedIconPadding(bool val)
{
userChangedIconPadding = val;
}
#region Bindable Properties
public static readonly BindableProperty modeProperty = BindableProperty.Create(nameof(mode), typeof(ButtonMode), typeof(FlexButton), ButtonMode.TextOnly);
public ButtonMode mode
{
get => (ButtonMode)GetValue(modeProperty);
set => SetValue(modeProperty, value);
}
public static readonly new BindableProperty BackgroundColorProperty = BindableProperty.Create(nameof(BackgroundColor), typeof(Color), typeof(FlexButton), Color.Transparent);
public new Color BackgroundColor
{
get => (Color)GetValue(BackgroundColorProperty);
set => SetValue(BackgroundColorProperty, value);
}
public static readonly BindableProperty HighlightBackgroundColorProperty = BindableProperty.Create(nameof(HighlightBackgroundColor), typeof(Color), typeof(FlexButton), Color.Transparent);
public Color HighlightBackgroundColor
{
get => (Color)GetValue(HighlightBackgroundColorProperty);
set => SetValue(HighlightBackgroundColorProperty, value);
}
public static readonly BindableProperty ForegroundColorProperty = BindableProperty.Create(nameof(ForegroundColor), typeof(Color), typeof(FlexButton), Color.Accent);
public Color ForegroundColor
{
get => (Color)GetValue(ForegroundColorProperty);
set => SetValue(ForegroundColorProperty, value);
}
public static readonly BindableProperty HighlightForegroundColorProperty = BindableProperty.Create(nameof(HighlightForegroundColor), typeof(Color), typeof(FlexButton), Color.White);
public Color HighlightForegroundColor
{
get => (Color)GetValue(HighlightForegroundColorProperty);
set => SetValue(HighlightForegroundColorProperty, value);
}
// Border Properties
public static readonly BindableProperty BorderColorProperty = BindableProperty.Create(nameof(BorderColor), typeof(Color), typeof(FlexButton), Color.Transparent);
public Color BorderColor
{
get => (Color)GetValue(BorderColorProperty);
set => SetValue(BorderColorProperty, value);
}
public static readonly BindableProperty HighlightBorderColorProperty = BindableProperty.Create(nameof(HighlightBorderColor), typeof(Color), typeof(FlexButton), Color.Transparent);
public Color HighlightBorderColor
{
get => (Color)GetValue(HighlightBorderColorProperty);
set => SetValue(HighlightBorderColorProperty, value);
}
public static readonly BindableProperty BorderThicknessProperty = BindableProperty.Create(nameof(BorderThickness), typeof(Thickness), typeof(FlexButton), new Thickness(0));
public Thickness BorderThickness
{
get => (Thickness)GetValue(BorderThicknessProperty);
set => SetValue(BorderThicknessProperty, value);
}
public static readonly BindableProperty CornerRadiusProperty = BindableProperty.Create(nameof(CornerRadius), typeof(int), typeof(FlexButton), 0);
public int CornerRadius
{
get => (int)GetValue(CornerRadiusProperty);
set => SetValue(CornerRadiusProperty, value);
}
public int InnerCornerRadius { get; private set; }
// Icon Properties
public static readonly BindableProperty IconProperty = BindableProperty.Create(nameof(Icon), typeof(ImageSource), typeof(FlexButton), null);
public ImageSource Icon
{
get => (ImageSource)GetValue(IconProperty);
set => SetValue(IconProperty, value);
}
public static readonly BindableProperty IconOrientationProperty = BindableProperty.Create(nameof(IconOrientation), typeof(IconOrientation), typeof(FlexButton), IconOrientation.Left);
public IconOrientation IconOrientation
{
get => (IconOrientation)GetValue(IconOrientationProperty);
set => SetValue(IconOrientationProperty, value);
}
public static readonly BindableProperty IconTintEnabledProperty = BindableProperty.Create(nameof(IconTintEnabled), typeof(bool), typeof(FlexButton), true);
public bool IconTintEnabled
{
get => (bool)GetValue(IconTintEnabledProperty);
set => SetValue(IconTintEnabledProperty, value);
}
// Text Properties
public static readonly BindableProperty TextProperty = BindableProperty.Create(nameof(Text), typeof(string), typeof(FlexButton), string.Empty);
public string Text
{
get => (string)GetValue(TextProperty);
set => SetValue(TextProperty, value);
}
public static readonly BindableProperty FontSizeProperty = BindableProperty.Create(nameof(FontSize), typeof(double), typeof(FlexButton), Device.GetNamedSize(NamedSize.Default, typeof(Label)));
[TypeConverter(typeof(FontSizeConverter))]
public double FontSize
{
get => (double)GetValue(FontSizeProperty);
set => SetValue(FontSizeProperty, value);
}
public static readonly BindableProperty FontAttributesProperty = BindableProperty.Create(nameof(FontAttributes), typeof(FontAttributes), typeof(FlexButton), (FontAttributes)Label.FontAttributesProperty.DefaultValue);
public FontAttributes FontAttributes
{
get => (FontAttributes)GetValue(FontAttributesProperty);
set => SetValue(FontAttributesProperty, value);
}
public static readonly BindableProperty FontFamilyProperty = BindableProperty.Create(nameof(FontFamily), typeof(string), typeof(FlexButton), (string)Label.FontFamilyProperty.DefaultValue);
public string FontFamily
{
get => (string)GetValue(FontFamilyProperty);
set => SetValue(FontFamilyProperty, value);
}
public static readonly BindableProperty MaxLinesProperty = BindableProperty.Create(nameof(MaxLines), typeof(int), typeof(FlexButton), 1);
public int MaxLines
{
get => (int)GetValue(MaxLinesProperty);
set => SetValue(MaxLinesProperty, value);
}
// Toggle Properties
public static readonly BindableProperty ToggleModeProperty = BindableProperty.Create(nameof(ToggleMode), typeof(bool), typeof(FlexButton), false);
public bool ToggleMode
{
get => (bool)GetValue(ToggleModeProperty);
set => SetValue(ToggleModeProperty, value);
}
public static readonly BindableProperty IsToggledProperty = BindableProperty.Create(nameof(IsToggled), typeof(bool), typeof(FlexButton), false, BindingMode.TwoWay);
public bool IsToggled
{
get => (bool)GetValue(IsToggledProperty);
set => SetValue(IsToggledProperty, value);
}
// Other Properties
public static readonly new BindableProperty PaddingProperty = BindableProperty.Create(nameof(Padding), typeof(Thickness), typeof(FlexButton), new Thickness(5,3), propertyChanged: (sender, obj, newVal) =>
{
//(sender as FlexButton).userChangedPadding = true;
//(sender as FlexButton).SetButtonMode();
});
public new Thickness Padding
{
get => (Thickness)GetValue(PaddingProperty);
set => SetValue(PaddingProperty, value);
}
public static readonly BindableProperty IconPaddingProperty = BindableProperty.Create(nameof(IconPadding), typeof(Thickness), typeof(FlexButton), new Thickness(2));
public Thickness IconPadding
{
get => (Thickness)GetValue(IconPaddingProperty);
set => SetValue(IconPaddingProperty, value);
}
public static readonly BindableProperty HasShadowProperty = BindableProperty.Create(nameof(HasShadow), typeof(bool), typeof(FlexButton), false);
public bool HasShadow
{
get => (bool)GetValue(HasShadowProperty);
set => SetValue(HasShadowProperty, value);
}
#endregion
#region Commands
public static readonly BindableProperty ClickedCommandProperty = BindableProperty.Create(nameof(ClickedCommand), typeof(ICommand), typeof(FlexButton), null, propertyChanged: (bindable, oldValue, newValue) => ((FlexButton)bindable).OnClickOrTouchedDownCommandPropertyChanged());
public ICommand ClickedCommand
{
get => (ICommand)GetValue(ClickedCommandProperty);
set => SetValue(ClickedCommandProperty, value);
}
public static readonly BindableProperty ClickedCommandParameterProperty = BindableProperty.Create(nameof(ClickedCommandParameter), typeof(object), typeof(FlexButton), null, propertyChanged: (bindable, oldValue, newValie) => ((FlexButton)bindable).CommandCanExecuteChanged(bindable, EventArgs.Empty));
public object ClickedCommandParameter
{
get => GetValue(ClickedCommandParameterProperty);
set => SetValue(ClickedCommandParameterProperty, value);
}
public static BindableProperty TouchedDownCommandProperty = BindableProperty.Create(nameof(TouchedDownCommand), typeof(ICommand), typeof(FlexButton), null);
public ICommand TouchedDownCommand
{
get { return (ICommand)GetValue(TouchedDownCommandProperty); }
set { SetValue(TouchedDownCommandProperty, value); }
}
public static readonly BindableProperty TouchedDownCommandParameterProperty = BindableProperty.Create(nameof(TouchedDownCommandParameter), typeof(object), typeof(FlexButton), null, propertyChanged: (bindable, oldValue, newValie) => ((FlexButton)bindable).CommandCanExecuteChanged(bindable, EventArgs.Empty));
public object TouchedDownCommandParameter
{
get => GetValue(TouchedDownCommandParameterProperty);
set => SetValue(TouchedDownCommandParameterProperty, value);
}
public static BindableProperty TouchedUpCommandProperty = BindableProperty.Create(nameof(TouchedUpCommand), typeof(ICommand), typeof(FlexButton), null);
public ICommand TouchedUpCommand
{
get => (ICommand)GetValue(TouchedUpCommandProperty);
set => SetValue(TouchedUpCommandProperty, value);
}
public static readonly BindableProperty TouchedUpCommandParameterProperty = BindableProperty.Create(nameof(TouchedUpCommandParameter), typeof(object), typeof(FlexButton), null, propertyChanged: (bindable, oldValue, newValie) => ((FlexButton)bindable).CommandCanExecuteChanged(bindable, EventArgs.Empty));
public object TouchedUpCommandParameter
{
get => GetValue(TouchedUpCommandParameterProperty);
set => SetValue(TouchedUpCommandParameterProperty, value);
}
#endregion
#region Events
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
}
protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
base.OnPropertyChanged(propertyName);
CalMode();
}
void OnClickOrTouchedDownCommandPropertyChanged()
{
if (ClickedCommand != null)
ClickedCommand.CanExecuteChanged += CommandCanExecuteChanged;
if (TouchedDownCommand != null)
TouchedDownCommand.CanExecuteChanged += CommandCanExecuteChanged;
CommandCanExecuteChanged(this, EventArgs.Empty);
}
void CommandCanExecuteChanged(object sender, EventArgs e)
{
// Define IsEnabled state
var canExecuteClick = ClickedCommand?.CanExecute(ClickedCommandParameter);
var canExecuteTouchedDown = TouchedDownCommand?.CanExecute(TouchedDownCommandParameter);
if (canExecuteClick != null && canExecuteTouchedDown != null)
IsEnabled = canExecuteClick == true && canExecuteTouchedDown == true;
else
IsEnabled = canExecuteClick == true || canExecuteTouchedDown == true;
}
protected override void OnPropertyChanging([CallerMemberName] string propertyName = null)
{
// Unsubscribe from command events when Command changes
if (propertyName == ClickedCommandProperty.PropertyName && ClickedCommand != null)
ClickedCommand.CanExecuteChanged -= CommandCanExecuteChanged;
if (propertyName == TouchedDownCommandProperty.PropertyName && TouchedDownCommandProperty != null)
TouchedDownCommand.CanExecuteChanged -= CommandCanExecuteChanged;
base.OnPropertyChanging(propertyName);
}
#endregion
void CalMode()
{
switch (IconOrientation)
{
case IconOrientation.Top: IconPadding = new Thickness(0, 0, 0, 6); break;
case IconOrientation.Left: IconPadding = new Thickness(0, 0, 6, 0); break;
case IconOrientation.Right: IconPadding = new Thickness(6, 0, 0, 0); break;
}
InnerCornerRadius = Math.Max(0, CornerRadius - (int)Math.Max(Math.Max(BorderThickness.Left, BorderThickness.Top), Math.Max(BorderThickness.Right, BorderThickness.Bottom)));
if (Icon != null && Text.Length > 0)
{
mode = ButtonMode.IconWithText;
}
else if (Icon != null && Text.Length == 0)
{
mode = ButtonMode.IconOnly;
}
else if (Icon == null && Text.Length > 0)
{
mode = ButtonMode.TextOnly;
}
SetButtonMode();
}
void SetButtonMode()
{
if (Icon != null && Text.Length > 0)
{
mode = ButtonMode.IconWithText;
}
else if (Icon != null && Text.Length == 0)
{
mode = ButtonMode.IconOnly;
}
else if (Icon == null && Text.Length > 0)
{
mode = ButtonMode.TextOnly;
}
switch (mode)
{
case ButtonMode.IconOnly:
if (ButtonIcon != null && ButtonText != null)
{
// Configure Container
//ContainerContent.HorizontalOptions = LayoutOptions.Fill;
Grid.SetColumnSpan(ButtonIcon, 2);
Grid.SetColumn(ButtonText, 1);
// Set Visibilities
ButtonText.IsVisible = false;
ButtonIcon.IsVisible = true;
}
// Adjust Default Padding
if (!userChangedPadding)
{
Padding = new Thickness(2);
userChangedPadding = false; // Set this back to false, as the above line triggers OnPropertyChanged
}
break;
case ButtonMode.IconWithText:
// Configure Container
switch (IconOrientation)
{
case IconOrientation.Top:
if(ContainerContent != null)
ContainerContent.Direction = FlexDirection.Column;
break;
case IconOrientation.Left:
if (ContainerContent != null)
ContainerContent.Direction = FlexDirection.Row;
break;
case IconOrientation.Right:
if (ContainerContent != null)
ContainerContent.Direction = FlexDirection.RowReverse;
break;
}
if (ButtonIcon != null && ButtonText != null)
{
// Set Visibilities
ButtonText.IsVisible = true;
ButtonIcon.IsVisible = true;
}
// Adjust Default Padding
/*
if (!userChangedPadding)
{
Padding = new Thickness(HeightRequest * .1, HeightRequest * .3);
userChangedPadding = false; // Set this back to false, as the above line triggers OnPropertyChanged
}
*/
if (!userChangedIconPadding)
{
switch (IconOrientation)
{
case IconOrientation.Top: IconPadding = new Thickness(0, 0, 0, 6); break;
case IconOrientation.Left: IconPadding = new Thickness(0, 0, 6, 0); break;
case IconOrientation.Right: IconPadding = new Thickness(6, 0, 0, 0); break;
}
}
break;
case ButtonMode.TextOnly:
// Configure Container
if (ButtonIcon != null && ButtonText != null)
{
//ContainerContent.HorizontalOptions = LayoutOptions.FillAndExpand;
Grid.SetColumnSpan(ButtonIcon, 1);
Grid.SetColumnSpan(ButtonText, 2);
Grid.SetColumn(ButtonText, 0);
// Set Visibilities
ButtonText.IsVisible = true;
ButtonIcon.IsVisible = false;
}
// Adjust Default Padding
/*
if (!userChangedPadding)
{
Padding = new Thickness(20, 0);
userChangedPadding = false; // Set this back to false, as the above line triggers OnPropertyChanged
}
*/
break;
}
// HACK: Horrible Hack, that makes the Xamarin.Forms Previewer work, who seems to give up some Binding support
// since Xamarin.Forms 2.5.1
try
{
if (Border != null)
{
Border.BackgroundColor = BorderColor;
Border.CornerRadius = CornerRadius;
Border.Padding = BorderThickness;
Border.HasShadow = HasShadow;
}
if (Container != null)
{
Container.BackgroundColor = BackgroundColor;
Container.CornerRadius = InnerCornerRadius;
ContainerContent.Margin = Padding;
}
if (ButtonText != null)
{
ButtonText.Text = Text;
ButtonText.FontSize = FontSize;
ButtonText.FontAttributes = FontAttributes;
ButtonText.FontFamily = FontFamily;
ButtonText.TextColor = ForegroundColor;
ButtonText.MaxLines = MaxLines;
}
if(ButtonIcon != null)
ButtonIcon.Margin = IconPadding;
}
catch (Exception ex)
{
}
if (ToggleMode)
{
Highlight(IsToggled);
}
// Calculate inner corner radius
// Use the outer radius minus the max thickness of a single direction
InnerCornerRadius = Math.Max(0, CornerRadius - (int)Math.Max(Math.Max(BorderThickness.Left, BorderThickness.Top), Math.Max(BorderThickness.Right, BorderThickness.Bottom)));
if(Container != null)
Container.CornerRadius = InnerCornerRadius;
//ColorIcon(ForegroundColor);
}
public event EventHandler<EventArgs> TouchedDown;
public event EventHandler<EventArgs> TouchedUp;
public event EventHandler<EventArgs> Clicked;
public event EventHandler<ToggledEventArgs> Toggled;
public FlexButton()
{
try
{
InitializeComponent();
}
catch (Exception ex)
{
}
//userChangedPadding = this.Padding.Equals(new Thickness(-1));
TouchRecognizer.TouchDown += TouchDown;
TouchRecognizer.TouchUp += TouchUp;
SizeChanged += FlexButton_SizeChanged;
}
void FlexButton_SizeChanged(object sender, EventArgs e)
{
// HACK: Needs to be called to not make the Designer do stupid things
//SetButtonMode();
ColorIcon(ForegroundColor);
}
void TouchDown()
{
if (IsEnabled)
{
TouchedDown?.Invoke(this, EventArgs.Empty);
TouchedDownCommand?.Execute(TouchedDownCommandParameter);
Highlight(true);
}
}
void TouchUp()
{
if (IsEnabled)
{
TouchedUp?.Invoke(this, EventArgs.Empty);
TouchedUpCommand?.Execute(TouchedUpCommandParameter);
Clicked?.Invoke(this, EventArgs.Empty);
ClickedCommand?.Execute(ClickedCommandParameter);
if (ToggleMode)
{
IsToggled = !IsToggled;
Toggled?.Invoke(this, new ToggledEventArgs(IsToggled));
Highlight(IsToggled);
}
else
{
Highlight(false);
}
}
}
void ColorIcon(Color color)
{
// Attach Color Overlay Effect
if (ButtonIcon == null) return;
ButtonIcon.Effects.Clear();
if (IconTintEnabled)
{
ButtonIcon.Effects.Add(new ColorOverlayEffect { Color = color });
}
}
void Highlight(bool isHighlighted)
{
if (Border == null || Container == null || ButtonText == null) return;
if (isHighlighted)
{
Border.BackgroundColor = HighlightBorderColor;
Container.BackgroundColor = HighlightBackgroundColor;
ButtonText.TextColor = HighlightForegroundColor;
ColorIcon(HighlightForegroundColor);
}
else
{
Border.BackgroundColor = BorderColor;
Container.BackgroundColor = BackgroundColor;
ButtonText.TextColor = ForegroundColor;
ColorIcon(ForegroundColor);
}
}
}
} `
Looks like the problem with Global Styles is, that they call OnPropertyChanged before the constructor has been called to initialize the object: https://stackoverflow.com/questions/46523431/xamarin-forms-bindableproperty-changed-before-constructor
@tomahutbui I'm no longer working on that project. :/ But thanks anyway.