XAML中Xamarin全局变量无法即时刷新,刷新时机随机
问题描述
我在App.xaml.cs中定义了三个全局静态变量:
public static bool _Code { get; set; } public static bool _Full { get; set; } public static bool _Common { get; set; }
在列表页面的XAML中,通过绑定这些变量控制Label的显示与隐藏:
<Grid> <Label Padding="4" BackgroundColor="{DynamicResource ColorWindowBackground}" HorizontalOptions="FillAndExpand" IsVisible="{Binding Path=_Code, Source={x:DynamicResource Application.Current}}" Text="{Binding CodeName}" VerticalOptions="FillAndExpand" /> <Label Padding="4" BackgroundColor="{DynamicResource ColorWindowBackground}" HorizontalOptions="FillAndExpand" IsVisible="{Binding Path=_Full, Source={x:DynamicResource Application.Current}}" Text="{Binding FullName}" VerticalOptions="FillAndExpand" /> <Label Padding="4" BackgroundColor="{DynamicResource ColorWindowBackground}" HorizontalOptions="FillAndExpand" IsVisible="{Binding Path=_Common, Source={x:DynamicResource Application.Current}}" Text="{Binding CommonName}" VerticalOptions="FillAndExpand" /> </Grid>
在另一页面中修改这些变量的值:
private string selectedDisplayType; public string SelectedDisplayType { get { return selectedDisplayType; } set { if (value != selectedDisplayType) { SetProperty(ref selectedDisplayType, value); if (selectedDisplayType != null) { //Update the Ui bools for showing the different types if (SelectedDisplayType == DisplayType.Common.ToString()) { SelectorEventObj.Common = true; App._Code = false; App._Common = true; App._Full = false; } else if (SelectedDisplayType == DisplayType.Code.ToString()) { SelectorEventObj.Code = true; App._Code = true; App._Common = false; App._Full = false; } else { SelectorEventObj.Full = true; App._Code = false; App._Common = false; App._Full = true; } } } }
但返回列表页面后,Label未按变量新值更新显示状态,仅在随意操作应用后随机刷新。需要让UI感知全局变量的变化。
解决方案
问题核心是静态变量未实现属性变更通知机制,XAML绑定无法自动感知变量值的变化,只有UI触发强制刷新时才会更新。解决方法如下:
1. 为App类添加属性变更通知
方案一:使用CommunityToolkit.Mvvm简化实现
先通过NuGet安装CommunityToolkit.Mvvm包,然后让App类继承ObservableObject,它已封装INotifyPropertyChanged逻辑:
using CommunityToolkit.Mvvm.ComponentModel; public partial class App : Application, ObservableObject { // 建议遵循PascalCase命名规范,比如IsCodeVisible而非_Code [ObservableProperty] private static bool isCodeVisible; [ObservableProperty] private static bool isFullVisible; [ObservableProperty] private static bool isCommonVisible; }
方案二:手动实现INotifyPropertyChanged
如果不想依赖第三方库,可手动实现接口:
public partial class App : Application, INotifyPropertyChanged { private static bool _code; public static bool _Code { get => _code; set { if (_code != value) { _code = value; Current.OnPropertyChanged(nameof(_Code)); } } } private static bool _full; public static bool _Full { get => _full; set { if (_full != value) { _full = value; Current.OnPropertyChanged(nameof(_Full)); } } } private static bool _common; public static bool _Common { get => _common; set { if (_common != value) { _common = value; Current.OnPropertyChanged(nameof(_Common)); } } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
2. 修正XAML绑定的Source
原绑定使用{x:DynamicResource Application.Current}不合适,应改为{x:Static App.Current}直接引用App静态实例,确保绑定源正确:
<Label Padding="4" BackgroundColor="{DynamicResource ColorWindowBackground}" HorizontalOptions="FillAndExpand" IsVisible="{Binding Path=_Code, Source={x:Static App.Current}}" Text="{Binding CodeName}" VerticalOptions="FillAndExpand" /> <!-- 另外两个Label同理修改Source -->
3. 保持变量修改逻辑不变
SelectedDisplayType的setter逻辑无需改动,只要确保赋值的是带通知的静态属性即可。
修改完成后,当在其他页面修改App._Code等变量时,属性变更通知会自动触发UI更新,返回列表页面后Label的显示状态会立即同步。
内容的提问来源于stack exchange,提问作者done_merson
相关产品推荐
相关产品推荐

