UWP跨类访问TextBox的IsEnabled属性失效问题求助
解决UWP中跨类修改TextBox启用状态不生效的问题
你现在遇到的核心问题很明确:你创建了一个全新的firstnavigatepage实例fnp,但这个实例并不是当前界面上正在显示的那个页面。当你调用fnp.text.IsEnabled=true时,你修改的是这个从未被加载、也从未出现在界面上的"新页面"里的TextBox,自然不会在你实际看到的界面上有任何效果。
下面给你几种可行的解决方案,按解耦程度从低到高排序:
方案一:传递已存在的页面实例(快速解决,适合简单场景)
如果peoplechatting页面是从firstnavigatepage导航过来的,你可以在导航时把当前显示的firstnavigatepage实例传过去,而不是在peoplechatting里新建一个:
- 在
firstnavigatepage的导航代码里,把自身作为参数传递:
// 假设这是你跳转到peoplechatting的代码 Frame.Navigate(typeof(peoplechatting), this);
- 在
peoplechatting里接收这个实例并保存:
private firstnavigatepage _existingPage; // 保存实际显示的页面实例 public peoplechatting() { this.InitializeComponent(); } protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); // 接收导航传递过来的页面实例 _existingPage = e.Parameter as firstnavigatepage; }
- 修改ToggleSwitch的事件代码,使用保存的实例:
public void MyToggle_Toggled(object sender, RoutedEventArgs e) { ToggleSwitch toggleSwitch = sender as ToggleSwitch; if (toggleSwitch != null && _existingPage != null) { if (toggleSwitch.IsOn) { MyEllipse.Fill = new SolidColorBrush(Colors.Green); toggleSwitch.OnContent = "Bot"; _existingPage.text.IsEnabled = true; // 修改实际页面的TextBox } else { // 可以加上关闭时的逻辑 MyEllipse.Fill = new SolidColorBrush(Colors.Gray); toggleSwitch.OnContent = "Manual"; _existingPage.text.IsEnabled = false; } } }
方案二:使用事件通知(解耦性更好,推荐)
直接跨类访问控件其实不符合面向对象的封装原则,更优雅的方式是通过事件通知:让peoplechatting在ToggleSwitch状态变化时触发事件,由firstnavigatepage自己处理TextBox的状态修改。
- 在
peoplechatting里定义事件:
// 定义事件,传递是否启用Bot的状态 public event EventHandler<bool> BotStateToggled; public void MyToggle_Toggled(object sender, RoutedEventArgs e) { ToggleSwitch toggleSwitch = sender as ToggleSwitch; if (toggleSwitch != null) { bool isBotEnabled = toggleSwitch.IsOn; MyEllipse.Fill = isBotEnabled ? new SolidColorBrush(Colors.Green) : new SolidColorBrush(Colors.Gray); toggleSwitch.OnContent = isBotEnabled ? "Bot" : "Manual"; // 触发事件,把状态传递出去 BotStateToggled?.Invoke(this, isBotEnabled); } }
- 在
firstnavigatepage里跳转到peoplechatting时,订阅这个事件:
private void NavigateToPeopleChatting() { var chatPage = new peoplechatting(); // 订阅事件,当状态变化时修改自己的TextBox chatPage.BotStateToggled += (s, isEnabled) => text.IsEnabled = isEnabled; Frame.Navigate(typeof(peoplechatting), chatPage); }
这种方式不需要把TextBox设为public,代码的耦合度更低,也更易维护。
方案三:MVVM绑定(适合复杂应用,最符合UWP设计理念)
如果你的应用涉及较多的状态同步,推荐使用MVVM模式,把ToggleSwitch和TextBox的状态绑定到同一个ViewModel的属性上,实现自动同步:
- 定义一个共享的ViewModel:
using System.ComponentModel; using System.Runtime.CompilerServices; public class ChatViewModel : INotifyPropertyChanged { private bool _isBotEnabled; public bool IsBotEnabled { get => _isBotEnabled; set { _isBotEnabled = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
- 在
App.xaml里把ViewModel设为全局资源:
<Application.Resources> <local:ChatViewModel x:Key="ChatViewModel"/> </Application.Resources>
- 在
firstnavigatepage的TextBox里绑定IsEnabled:
<TextBox x:Name="text" IsEnabled="{Binding IsBotEnabled, Source={StaticResource ChatViewModel}}"/>
- 在
peoplechatting的ToggleSwitch里绑定IsOn:
<ToggleSwitch x:Name="MyToggle" IsOn="{Binding IsBotEnabled, Source={StaticResource ChatViewModel}}" OnContent="Bot" OffContent="Manual"/>
这样ToggleSwitch状态变化时,TextBox的启用状态会自动同步,甚至不需要写Toggled事件的逻辑(如果只需要状态同步的话)。
内容的提问来源于stack exchange,提问作者user9180315
相关产品推荐
相关产品推荐

