问题描述
我开发了一个可以播放音频流源的 Xamarin.Forms 应用。
我想在短时间内显示一条错误消息而不是当前标题,当发生错误时(例如无法访问互联网或 URL 无法访问) ),在 2 种 Labels
之间有一个小动画/过渡。
为此,我在 viewmodel 中有一个 HasError
属性:
bool hasError = false;
public bool HasError
{
get { return hasError; }
set { SetProperty(ref hasError,value); }
}
我想通过 Triggers
来管理这个。
我可以这样做:
<Label x:Name="RadioName"
Text="{Binding CurrentTitle}"
Style="{StaticResource RadioLabelStyle}"
Grid.Column="1">
<Label.Triggers>
<DataTrigger Binding="{Binding HasError}" Value="false" targettype="Label">
<Setter Property="IsVisible" Value="True" />
</DataTrigger>
<DataTrigger Binding="{Binding HasError}" Value="true" targettype="Label">
<Setter Property="IsVisible" Value="False" />
</DataTrigger>
</Label.Triggers>
</Label>
<Label x:Name="RadioError"
Text="{x:Static strings:Strings.RadioErrorAccessMessage}"
Style="{StaticResource ErrorRadioLabelStyle}"
Grid.Column="1">
<Label.Triggers>
<DataTrigger Binding="{Binding HasError}" Value="false" targettype="Label">
<Setter Property="IsVisible" Value="False" />
</DataTrigger>
<DataTrigger Binding="{Binding HasError}" Value="true" targettype="Label">
<Setter Property="IsVisible" Value="True" />
</DataTrigger>
</Label.Triggers>
</Label>
这很好用,但在这种情况下,我没有任何时间限制或任何过渡/动画。
是否可以添加时间限制和过渡/动画?
解决方法
- xaml 部分使用 MultiTrigger,这里是一个带有
Label
的示例
<Label TextColor="Black" Text="Online" FontSize="25">
<Label.Triggers>
<MultiTrigger TargetType="{x:Type Label}">
<MultiTrigger.Conditions>
<BindingCondition Binding="{Binding ConnectionStatus}" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="BackgroundColor" Value="Orange"/>
<Setter Property="Text" Value="Error Connection Lost"/>
</MultiTrigger>
</Label.Triggers>
</Label>
- 定义
ConnectionStatus
属性
private bool _ConnectionStatus = true;
public bool ConnectionStatus
{
get => _ConnectionStatus;
set => SetProperty(ref _ConnectionStatus,value); //raise InotifyPropertyChanged
}
注意:我没有包含 Inotifyproperty 事件代码(这里有很多关于它的答案)
- 逻辑部分:对于丢失的连接,您可以使用 Xamarin Essentials 中的 ConnectivityChanged 事件:
- 订阅活动
protected override void OnAppearing()
{
base.OnAppearing();
Connectivity.ConnectivityChanged += Connectivity_ConnectivityChanged;
}
- 取消订阅活动
protected override void OnDisappearing()
{
base.OnDisappearing();
Connectivity.ConnectivityChanged -= Connectivity_ConnectivityChanged;
}
- 处理事件:连接丢失后会显示错误信息5秒。
async void Connectivity_ConnectivityChanged(object sender,ConnectivityChangedEventArgs e)
{
var access = e.NetworkAccess;
if (access != NetworkAccess.Internet)
{
VM.ConnectionStatus = false;
await Task.Delay(TimeSpan.FromSeconds(5));
VM.ConnectionStatus = true;
}
}
注意
VM
是对您的视图模型的引用,其中应该定义 ConnectionStatus
,也不要忘记正确设置您的页面 BindingContext
。
如果您不想使用视图模型,只需在您的代码而不是视图模型中定义 ConnectionStatus
属性(和句柄 INotifyPropertyChanged
)也没有问题。在这种情况下,ConnectionStatus = false;
和 `BindingContext = this;.