Xamarin обязательное свойство базового вида
У меня есть базовое представление XAML, в котором есть пользовательский элемент управления с привязываемым свойством, которое используется для отображения / скрытия Grid
контроль. Мне нужно изменить это свойство из представления XAML, которое наследуется от базового представления.
пользовательский вид управления
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));
}
}
}
его мнение
<?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>
базовый класс
namespace TEST_SF.Base
{
public class BaseClass
{
public static VolosLoading PageLoading = new VolosLoading { Mostra = false };
}
}
базовый вид
<?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>
Затем у меня есть представление, которое наследуется от базового представления с помощью кнопки, которая вызывает команду, которая выполняет этот код:
PageLoading.Mostra = !PageLoading.Mostra;
Класс это:
class MainPage_Repo : Base.BaseClass
его мнение:
<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>
Проблемы в том, что Grid
виден при запуске, а при нажатии кнопки ничего не меняется, значение Mostra
изменен правильно, но он Grid
всегда видно
Как я могу решить это?
2 ответа
Если у вас есть статические свойства в ContentView
Ожидаются странные проблемы, так как они распределяются между экземплярами, в вашем случае, что касается _LoadingContainer
Даже если это не решит вашу проблему, это то, что может вызвать огромные проблемы и не должно быть сделано.
Проблема в том, когда вы звоните:
_LoadingContainer = (Grid)FindByName("LoadingContainer");
Эта строка создает копию Grid
контейнер, определенный в XAML x:Name="LoadingContainer"
, Затем, когда Mostra
изменения свойств, вы затем делаете:
_LoadingContainer.IsEnabled = (bool)newValue;
_LoadingContainer.IsVisible = (bool)newValue;
Вышесказанное позволяет получить доступ и изменить свойства копии Grid
вид, а не факт LoadingContainer
сам.
Заменить все экземпляры _LoadingContainer
с LoadingContainer
и ваша проблема должна быть решена.
Кроме того, вы можете удалить привязки к IsVisible
а также IsEnabled
свойства Grid
, Это приведет к ненужной сложности в скомпилированном коде.
РЕДАКТИРОВАТЬ
Кроме того, в вашем MostraPropertyChanged
обработчик, вы должны изменить его на следующее:
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;
}
}