You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 20:48:19