Reputation: 599
I have a base XAML View that have a custom control with bindable property that is used to show/hide a Grid
control.
I need to change this property from a XAML View that inherit from the base View.
the custom control view
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using Syncfusion.SfBusyIndicator.XForms;
using System.Runtime.CompilerServices;
namespace TEST_SF
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class VolosLoading : ContentView
{
private static Grid _LoadingContainer = null;
public bool Mostra
{
get { return (bool)GetValue(MostraProperty); }
set { SetValue(MostraProperty, value); OnPropertyChanged(nameof(Mostra)); }
}
public static BindableProperty MostraProperty = BindableProperty.Create(
propertyName: nameof(Mostra),
returnType: typeof(bool),
declaringType: typeof(VolosLoading),
defaultValue: false,
defaultBindingMode: BindingMode.TwoWay
, propertyChanged: MostraPropertyChanged
);
private static void MostraPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
_LoadingContainer.IsEnabled = (bool)newValue;
_LoadingContainer.IsVisible = (bool)newValue;
}
public VolosLoading()
{
InitializeComponent();
_LoadingContainer = (Grid)FindByName("LoadingContainer");
OnPropertyChanged(nameof(Mostra));
}
}
}
its view
<?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:busyindicator="clr-namespace:Syncfusion.SfBusyIndicator.XForms;assembly=Syncfusion.SfBusyIndicator.XForms"
x:Class="TEST_SF.VolosLoading">
<ContentView.Content>
<Grid x:Name="LoadingContainer" IsEnabled="{Binding Mostra}" IsVisible="{Binding Mostra}">
<Grid BackgroundColor="LightGray" Opacity="0.6" />
<busyindicator:SfBusyIndicator x:Name="Loading" AnimationType="DoubleCircle"
ViewBoxWidth="150" ViewBoxHeight="150"
TextColor="Green" BackgroundColor="Transparent"
HorizontalOptions="Center" VerticalOptions="Center" />
</Grid>
</ContentView.Content>
</ContentView>
the base class
namespace TEST_SF.Base
{
public class BaseClass
{
public static VolosLoading PageLoading = new VolosLoading { Mostra = false };
}
}
the base view
<?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:TEST_SF"
x:Class="TEST_SF.BasePage">
<ContentPage.ControlTemplate>
<ControlTemplate>
<StackLayout>
<Label BackgroundColor="Red" Text="Welcome to Xamarin.Forms!"
VerticalOptions="StartAndExpand"
HorizontalOptions="CenterAndExpand" />
<local:VolosLoading></local:VolosLoading>
<ContentPresenter></ContentPresenter>
</StackLayout>
</ControlTemplate>
</ContentPage.ControlTemplate>
</ContentPage>
Then I have a view that inherit from the base View with a button that calls a command that execute this code:
PageLoading.Mostra = !PageLoading.Mostra;
The class is:
class MainPage_Repo : Base.BaseClass
its view:
<local:BasePage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TEST_SF"
x:Class="TEST_SF.MainPage">
<ContentPage.BindingContext>
<local:MainPage_Repo />
</ContentPage.BindingContext>
<StackLayout>
<Button VerticalOptions="Center" HorizontalOptions="Center" Text="Loading SF" Command="{Binding MyMockCommand}" CommandParameter="1" />
</StackLayout>
</local:BasePage>
The problems are that the Grid
is visible at start, and when the button is pressed nothing changes, the value of Mostra
is changed correctly but he Grid
is always visible.
How can i solve this?
Upvotes: 0
Views: 1054
Reputation: 9990
If you have static properties in ContentView
, weird problems are expected to happen, as they are shared across instances, in your case that relates to the _LoadingContainer
Even if this doesn't resolve your problem that is something that can cause huge problems and shouldn't be done.
Upvotes: 1
Reputation: 1749
The problem is when you are calling:
_LoadingContainer = (Grid)FindByName("LoadingContainer");
This line is creating a copy of the Grid
container defined in the XAML by x:Name="LoadingContainer"
. Then, when the Mostra
property changes, you are then doing:
_LoadingContainer.IsEnabled = (bool)newValue;
_LoadingContainer.IsVisible = (bool)newValue;
The above is accessing and changing the properties of the copy of the Grid
view, not the actual LoadingContainer
itself.
Replace all instances of _LoadingContainer
with LoadingContainer
, and your problem should be solved.
Also, you can remove the bindings to the IsVisible
and IsEnabled
properties of the Grid
. These will cause unnecessary complexity in the compiled code.
EDIT
In addition, in your MostraPropertyChanged
handler, you should change it to the following:
private static void MostraPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
var control = (VolosLoading)bindable;
if (control != null)
{
control.LoadingContainer.IsEnabled = (bool)newValue;
control.LoadingContainer.IsVisible = (bool)newValue;
}
}
Upvotes: 0