我有一个要求,例如ActivityIndicator
将在执行API调用时出现。所有页面都一样。因此我创建了BasePage并将活动指示器放置在BasePage.xaml
中。
BasePage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
x:Class="XamarinFormDemo.Base.BasePage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
<ContentPage.ControlTemplate>
<ControlTemplate x:Name="baseTemplate">
<AbsoluteLayout
AbsoluteLayout.LayoutBounds="1,1,1,1"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<ContentPresenter AbsoluteLayout.LayoutBounds="0, 0, 1, 1" AbsoluteLayout.LayoutFlags="All" />
<StackLayout
x:Name="stackProgress"
AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All"
BackgroundColor="#8C000000"
HorizontalOptions="FillAndExpand"
IsVisible="False"
Orientation="Vertical"
VerticalOptions="FillAndExpand">
<ActivityIndicator
x:Name="indicatorProgress"
AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All"
HorizontalOptions="Center"
IsRunning="True"
VerticalOptions="FillAndExpand"
Color="White" />
</StackLayout>
</AbsoluteLayout>
</ControlTemplate>
</ContentPage.ControlTemplate>
</ContentPage>
我创建了一些方法来处理ActivityIndicator状态,例如在需要时显示可见和不可见。
BasePage.xaml.cs
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class BasePage : ContentPage
{
public BasePage()
{
InitializeComponent();
}
/*
* Show progress dialog
*/
public void ShowProgress()
{
if (!stackProgress.IsVisible)
{
stackProgress.IsVisible = true;
}
}
/*
* Hide progress dialog
*/
public void HideProgress()
{
stackProgress.IsVisible = false;
}
}
现在,我已经创建了LoginPage.xaml并将BasePage添加为根控件。这样我就可以访问指标。我在其他页面上也做过同样的事情。
LoginPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<base:BasePage
x:Class="XamarinFormDemo.MainPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:base="clr-namespace:XamarinFormDemo.Base"
xmlns:local="clr-namespace:XamarinFormDemo.Controls"
BackgroundColor="#2b3d53"
NavigationPage.HasNavigationBar="False">
<ScrollView>
<StackLayout
Padding="24"
HorizontalOptions="FillAndExpand"
Orientation="Vertical"
VerticalOptions="FillAndExpand">
<Image
Margin="0,32,0,32"
HeightRequest="100"
Source="ai_logo.jpg"
VerticalOptions="Center"
WidthRequest="100" />
<local:CustomEntry
x:Name="entryEmail"
Margin="0,0,0,8"
DrawableImage="email_hover_icon"
FontSize="Small"
IsSpellCheckEnabled="False"
Keyboard="Email"
Placeholder="Email"
PlaceholderColor="Gray"
Text="peter@klaven.com"
TextColor="Black" />
<local:CustomEntry
x:Name="entryPassword"
Margin="0,0,0,8"
DrawableImage="password_hover_icon"
FontSize="Small"
IsPassword="True"
IsSpellCheckEnabled="False"
Placeholder="Password"
PlaceholderColor="Gray"
Text="cityslicka"
TextColor="Black" />
<Button
x:Name="buttonLogin"
Margin="0,16,0,16"
BackgroundColor="#009999"
Clicked="ButtonLogin_ClickedAsync"
FontSize="Small"
Text="Login"
TextColor="White" />
<Label
FontSize="Small"
HorizontalOptions="Center"
Text="OR"
TextColor="White" />
<Button
x:Name="buttonSignUp"
Margin="0,16,0,16"
BackgroundColor="#009999"
Clicked="NavigateToSignUp"
FontSize="Small"
Text="SignUp"
TextColor="White" />
</StackLayout>
</ScrollView>
</base:BasePage>
在 LoginPage.xaml.cs 文件中,我有使用ShowProgress();
和HideProgress();
进行登录和处理活动指示器的调用代码
这些方法属于 BasePage.xaml.cs 。
LoginPage.xaml.cs
namespace XamarinFormDemo
{
public partial class MainPage : BasePage
{
public MainPage()
{
InitializeComponent();
}
private async Task ButtonLogin_ClickedAsync(object sender, EventArgs e)
{
ShowProgress();
// API Call
HideProgress();
}
}
}
我想要如下输出。请看图片。
View should be like this when the ActivityIndicator is hidden
View should be like this when calling API
问题是,我无法在后面的代码中访问“ stackProgress”。因为它是ControlTemplate
。就是说
名称“ stackProgress”在当前上下文中不存在。
还有其他方法可以实现同一目标吗?或
有人可以告诉我我做错了什么吗?
我该如何解决?
答案 0 :(得分:0)
请尝试以下代码:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
x:Class="XamarinFormDemo.Base.BasePage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
<ContentPage.Content>
<AbsoluteLayout
x:Name="dd"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<ContentView x:Name="baseTemplate">
<StackLayout
x:Name="stackProgress"
AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All"
BackgroundColor="#8C000000"
HorizontalOptions="FillAndExpand"
Orientation="Vertical"
VerticalOptions="FillAndExpand">
</StackLayout>
</ContentView>
<StackLayout Padding="12" x:Name="DisplayLoading"
IsVisible="False"
AbsoluteLayout.LayoutFlags="PositionProportional"
AbsoluteLayout.LayoutBounds="0.5,0.5,-1,-1">
<ActivityIndicator Color="#d7813e" IsRunning="True"/>
<Label Text="Loading..." TextColor="#d7813e" FontSize="Small"/>
</StackLayout>
<ContentPage.Content>
尝试使用CS代码,例如:
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class BasePage : ContentPage
{
public BasePage()
{
InitializeComponent();
}
/*
* Show progress dialog
*/
public void ShowProgress()
{
DisplayLoading.IsVisible = true;
}
/*
* Hide progress dialog
*/
public void HideProgress()
{
DisplayLoading.IsVisible = false;
}
}
答案 1 :(得分:0)
我建议您使用TemplateBinding。
因此基本上,您可以在控制模板中重用IsBusy属性:
<ControlTemplate x:Name="baseTemplate">
<AbsoluteLayout ..>
<ContentPresenter AbsoluteLayout.LayoutBounds="0, 0, 1, 1" AbsoluteLayout.LayoutFlags="All" />
<StackLayout
x:Name="stackProgress"
...
IsVisible="{TemplateBinding IsBusy}"
...>
<ActivityIndicator
...
IsRunning="{TemplateBinding IsBusy}"
IsVisible="{TemplateBinding IsBusy}"
Color="White" />
</StackLayout>
</AbsoluteLayout>
</ControlTemplate>
现在,您可以使用MVVM绑定此IsBusy
属性,也可以在后台代码中更新方法:
/*
* Show progress dialog
*/
public void ShowProgress()
{
if (!IsBusy)
{
IsBusy = false;
}
}
/*
* Hide progress dialog
*/
public void HideProgress()
{
IsBusy = false;
}