使用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
相关产品推荐
相关产品推荐

