【问题标题】:Hide/Unhide XAML Elements With Button Clicked单击按钮隐藏/取消隐藏 XAML 元素
【发布时间】:2021-05-04 21:02:17
【问题描述】:

当我提出WebService 请求时,我一直在尝试实现这个ActivityIndicator。我已经通过了几种不同的解决方案,我正在尝试最简单的一种,如下所示:

https://www.youtube.com/watch?v=FmX4RD2iyWw

嗯,它不适合我。在我看来,它不接受我想给变量的新值。当我通过代码将 IsVisible 变量设置为 true 时,我可以看到那里的旋转圆圈,但是,当我将变量设置为 false 并单击按钮时,没有任何反应。此外,应该有一个“空白”空间对应于不存在的元素。

任何帮助将不胜感激。

非常感谢!

LoginPage.xaml:

<ContentPage.Content>
  <StackLayout>
    <ActivityIndicator x:Name="activityIndicator" IsVisible="false" IsRunning="True" WidthRequest="30" HeightRequest="30"/>
  </StackLayout>
</ContentPage.Content>

<Button Text="Sign In" Clicked="SignIn" />

LoginPage.xaml.cs:

void SignIn(object sender, EventArgs e)
  {
    activityIndicator.IsVisible = true;
    Method();
    activityIndicator.IsVisible = false;
  }

【问题讨论】:

  • 取决于 Method 正在做什么,它可能会阻塞 UI 线程,因此 ActivityIndi​​cator 在 Method 完成之前无法更新
  • 您不能按照您尝试的方式执行此操作。在 SignIn 方法完成之前,不会重新布局显示。因此,如果您以“假”开始,您将永远看不到任何东西。并且不会为它保留空白空间 - 了解 IsVisible 的作用。寻找活动指示器的一些不同的工作示例。或者您遗漏了该 youtube 中的一些小细节? (我没看过。)有没有提到使用 async/await?还是Task.Run?抱歉,我没有详细信息,但基本上你需要在“登录”运行时不阻塞 UI 线程。另一种解决方案是控制不透明度。
  • @Rafael 你的按钮在内容页面之外怎么样?你能在 SignIn 方法中达到调试点吗?
  • 感谢 cmets!总的来说,我已经能够调试,并且在按下按钮时我可以看到可见性标志从 true 变为 false
  • @ToolmakerSteve 我认为阻塞 UI 线程的方法的想法是一个很好的猜测......我会检查你提到的这些细节。谢谢!

标签: c# xaml xamarin.forms show-hide activity-indicator


【解决方案1】:

在 cmets 的帮助下,我进行了一些小改动,使其正常工作。我相信 await 命令是我遗漏的细节之一。 我不确定这是否是最好的解决方案。我很确定我应该为此使用某种标志,但我仍然不能这样做。

以下两种解决方案:

1.通过将IsVisible 属性设置为FALSE,您可以隐藏ActivityIndicator 而没有为元素保留空间

LoginPage.xaml:

<ContentPage.Content>
  <StackLayout>
    <ActivityIndicator x:Name="activityIndicator" IsVisible="false" IsRunning="True" WidthRequest="30" HeightRequest="30"/>
    <Button Text="Sign In" Clicked="SignIn" />
  </StackLayout>
</ContentPage.Content>

LoginPage.xaml.cs:

async void SignIn(object sender, EventArgs e)
  {
    activityIndicator.IsVisible = true;
    await Task.Delay(500);
    Method();
    activityIndicator.IsVisible = false;
  }

2。通过将IsRunning 属性设置为FALSE,您可以隐藏ActivityIndicator 并为元素保留保留空间

LoginPage.xaml:

<ContentPage.Content>
  <StackLayout>
    <ActivityIndicator x:Name="activityIndicator" IsVisible="True" IsRunning="False" WidthRequest="30" HeightRequest="30"/>
    <Button Text="Sign In" Clicked="SignIn" />
  </StackLayout>
</ContentPage.Content>

LoginPage.xaml.cs:

async void SignIn(object sender, EventArgs e)
  {
    activityIndicator.IsRunning = true;
    await Task.Delay(500);
    Method();
    activityIndicator.IsRunning = false;
  }

【讨论】:

  • 使用await时,方法要声明async:async void SignIn(...
  • hidden: no blank space reserved。确切地。这是IsVisible 的定义行为。如果你想保留空间;将 Opacity 设置为 0(不可见)或 1(完全可见)。 (删除IsVisible 属性,或使用IsVisible="true")您还可以将Opacity 设置为分数,以使部分可见;例如0.5 是半可见的,半透明的。 (如果 Opacity 0 不保留空间,请设置一个非常小的数字,例如 0.001 - 这在 iOS 上的某些情况下曾经是必需的。)
  • &lt;Button Text="Sign In" Clicked="SignIn" /&gt; 行应该在 inside StackLayout。将其移动到ActivityIndicator 之后和&lt;/StackLayout&gt; 行之前的下一行。请测试此更改,如果可行,请编辑您的答案以显示更正后的代码。
  • 我认为你可以只设置属性IsRunning 而不是IsVisible
  • 性能方面,最好使用不透明度。原因:不必在每次显示/隐藏元素时都执行布局。 ActivityIndi​​cator 不应该旋转 - 绑定到它的 IsRunning 属性,实际上,您甚至可能不需要隐藏它。如果手动设置IsRunning=False,是不是只显示一个空白区域?它可能会做你想做的事!然后将 "False" 替换为您更改的值,而不是对 IsVisible 执行此操作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-18
  • 1970-01-01
  • 1970-01-01
  • 2017-12-14
  • 2013-08-10
  • 1970-01-01
相关资源
最近更新 更多