WPF练习开发扫雷时StackPanel的DataContext无法找到row对象问题
修复步骤
- 修正MainWindow上下文绑定源问题
- 修复RowUpper类属性递归、通知不匹配、计时器失效问题
- 调整XAML绑定逻辑
1. 修改MainWindow.xaml.cs
原代码中row是构造函数局部变量,绑定无法访问,改为公共属性并指定窗口DataContext:
public partial class MainWindow : Window { // 改为公共属性,绑定才能识别访问 public RowUpper row { get; set; } public MainWindow() { InitializeComponent(); row = new RowUpper(); // 指定窗口DataContext为当前实例,{Binding row}才能找到对应源 this.DataContext = this; // 启动计时器测试 RowUpper.ResetTimer(); } // 其余业务代码保持不变 }
2. 修改RowUpper.cs
修复属性递归、通知参数错误、计时器自动释放、跨线程更新问题:
namespace MineSweeper { public class RowUpper : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged = delegate { }; // 私有字段存储属性值,避免递归调用 private string _timeshown; private static int _time = 0; // 静态存储计时器,避免using作用域结束后被自动释放 private static Timer _timer; public static RowUpper row = new RowUpper(); public string timeshown { get { return _timeshown; } set { _timeshown = value; // 通知参数名和属性名保持完全一致才能触发UI更新 PropertyChanged(this, new PropertyChangedEventArgs(nameof(timeshown))); } } public static void ResetTimer() { _time = 0; _timer = new Timer(1000); _timer.Elapsed += OnTimedEvent; _timer.Start(); } private static void OnTimedEvent(object source, System.Timers.ElapsedEventArgs e) { _time++; // 用静态实例更新属性触发通知 row.timeshown = _time.ToString(); } } }
3. 修改MainWindow.xaml
移除重复的DataContext设置,直接绑定Text属性即可:
<Window x:Class="MineSweeper.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:minesweeper="clr-namespace:MineSweeper" mc:Ignorable="d" Title="MineSweeper" Height="920" Width="920"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="80"/> <RowDefinition Height="900"/> </Grid.RowDefinitions> <StackPanel x:Name="Stackpanel" Grid.Row="0" DataContext="{Binding row}" VerticalAlignment="Top" Height="80"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="40"/> <RowDefinition Height="40"/> </Grid.RowDefinitions> <!--其余控件代码保持不变--> <!--去掉TextBox的DataContext设置,直接绑定Text属性--> <TextBox x:Name="ZeitAnzeigeTB" TextAlignment="Right" Text="{Binding timeshown}" Width="389" Height="40" HorizontalAlignment="Left" FontSize="25" Grid.Row="1" IsReadOnly="True" Margin="70 0 0 0" BorderThickness="0" IsTabStop="True"/> <!--其余控件代码保持不变--> </Grid> </StackPanel> </Grid> </Window>
内容的提问来源于stack exchange,提问作者birni
相关产品推荐
相关产品推荐

