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

使用C#获取XAML中Toggle Switch值并同步不同文件的两个开关

问题原因说明

你遇到的非静态对象引用报错,是因为尝试在无页面实例的上下文(比如静态方法、其他类)直接访问页面实例的toggleSwitch1控件,XAML中声明的命名控件是所属页面类的实例成员,必须依托页面实例才能访问。

推荐解决方案:MVVM绑定(无额外同步逻辑)

这是最优雅的实现方案,两个开关绑定同一个全局状态源,自动实现双向同步,无需手动写同步逻辑:

1. 创建全局视图模型

public class GlobalToggleViewModel : INotifyPropertyChanged
{
    private bool _isToggled = true;
    public bool IsToggled
    {
        get => _isToggled;
        set
        {
            if (_isToggled == value) return;
            _isToggled = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

2. 注册全局实例

在App.xaml.cs中添加静态全局实例,供两个页面绑定使用:

public partial class App : Application
{
    public static GlobalToggleViewModel ToggleViewModel { get; } = new GlobalToggleViewModel();
    // 保留其余原有代码
}

3. 两个XAML开关绑定同一状态

将两个不同文件的Switch都改成如下绑定写法,Toggled事件仅需处理自身业务逻辑即可:

<Switch Grid.Column="1" 
        IsToggled="{Binding Source={x:Static local:App.ToggleViewModel}, Path=IsToggled, Mode=TwoWay}"
        Toggled="OnToggled"/>

4. 优化原有Toggled事件代码

不需要直接访问toggleSwitch1,通过sender参数获取触发事件的开关实例,彻底解决对象引用报错:

void OnToggled(object sender, ToggledEventArgs e)
{
    //updateConsentValueForCategory();
    var currentSwitch = (Switch)sender;
    if (currentSwitch.IsToggled)
    {
        Console.WriteLine("Toggled on");
    }
    else
    {
        Console.WriteLine("Toggled off");
    }
}
轻量替代方案:静态状态事件通知

如果不想引入MVVM结构,可通过静态类托管状态+事件通知的方式实现同步:

1. 定义静态状态管理类

public static class ToggleSyncManager
{
    private static bool _isToggled = true;
    public static bool IsToggled
    {
        get => _isToggled;
        set
        {
            if (_isToggled == value) return;
            _isToggled = value;
            ToggledStateChanged?.Invoke(null, _isToggled);
        }
    }
    // 状态变更通知事件
    public static event EventHandler<bool> ToggledStateChanged;
}

2. 每个开关页面处理同步逻辑

每个包含Switch的页面订阅状态变更事件,开关切换时更新全局静态状态即可:

// 页面显示时订阅事件、初始化状态
protected override void OnAppearing()
{
    base.OnAppearing();
    toggleSwitch1.IsToggled = ToggleSyncManager.IsToggled;
    ToggleSyncManager.ToggledStateChanged += OnToggleStateSynced;
}

// 页面隐藏时取消订阅避免内存泄漏
protected override void OnDisappearing()
{
    base.OnDisappearing();
    ToggleSyncManager.ToggledStateChanged -= OnToggleStateSynced;
}

// 接收全局状态变更,更新当前页面开关
private void OnToggleStateSynced(object sender, bool newState)
{
    toggleSwitch1.IsToggled = newState;
}

// 开关切换时更新全局状态
void OnToggled(object sender, ToggledEventArgs e)
{
    ToggleSyncManager.IsToggled = e.Value;
    // 保留其余业务逻辑
    if (e.Value)
    {
        Console.WriteLine("Toggled on");
    }
    else
    {
        Console.WriteLine("Toggled off");
    }
}

内容的提问来源于stack exchange,提问作者JM Wesierski

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 21:15:06