【问题标题】:Data Context can´t find object数据上下文找不到对象
【发布时间】:2022-01-08 18:11:37
【问题描述】:

我对 wpf 相当陌生,并试图编写一个扫雷游戏作为练习。我的问题是我无法获取我的Stackpanel 的数据上下文来查找对象row,除非我将整个窗口的数据上下文设置为RowUpper 类,如下面的代码所示。 尝试将行对象作为RowUpper 类的字段或作为MainWindow 类中的普通对象。我想为文本框ZeitAnzeigeTB 提供timeShown 字段的值,以便能够显示计数器。

MainWindow.xaml.cs:

public partial class MainWindow : Window
{
        public MainWindow()
        {
            InitializeComponent();
            RowUpper row = new RowUpper();
        }
        //some more code
}

Mainwindow.xaml:

<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:local="clr-namespace:QuizApp" 
        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>
               
                //some more buttons and textboxes
                
                <TextBox x:Name="ZeitAnzeigeTB" TextAlignment="Right" DataContext="{Binding timeshown}" Width="389" Height="40" HorizontalAlignment="Left" FontSize="25" Grid.Row="1" IsReadOnly="True" Margin="70 0 0 0" BorderThickness="0" IsTabStop="True"/>
                //even more textboxes and buttons
            </Grid>
        </StackPanel>
    </Grid>
</Window>

RowUpper.cs:

namespace MineSweeper
{
    public class RowUpper : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged = delegate { };

        public static RowUpper row = new RowUpper();
        private int time = 0;
        public string timeshown
        {
            get
            {
                return timeshown;
            }

            set
            {
                timeshown = value;
                PropertyChanged(this, new PropertyChangedEventArgs("timeShown"));
            }
        }
        public static void ResetTimer()
        {   
            using Timer Timer = new(1000);
            Timer.Start();
            Timer.Elapsed += OnTimedEvent;
        }

        private static void OnTimedEvent(object source, System.Timers.ElapsedEventArgs e)
        {
            time++;
            timeshown = time.ToString();
        }
    }
}

【问题讨论】:

  • 您只能绑定到当前数据上下文的属性上,row 甚至不是MainWindow 的成员,它只存在于构造函数内部,而不是在构造函数之前和之后。你也没有在任何地方设置你的DataContext,如果你想绑定到后面代码的属性,你需要this
  • 作为return timeshown; 来自timeshown 属性的getter 的注释将不起作用。您需要该属性的支持字段。
  • 哦,是的,谢谢。由于您的提示,它现在可以工作了。看了一整套关于这个的复数课程,但我还不能真正理解它。

标签: c# wpf data-binding


【解决方案1】:

表达式

DataContext="{Binding row}"

只有在 current DataContext 中有一个公共属性 row 才会起作用,但显然情况并非如此。

像在 XAML 中那样设置 DataContexts 并不是数据绑定的工作方式。

在最简单的情况下,你会拥有这个构造函数:

public MainWindow()
{
    InitializeComponent();
    DataContext = new RowUpper();
}

并将 UI 元素的属性绑定到当前 DataContext 中的 RowUpper 对象的属性,如

<TextBox Text="{Binding timeshown}" .../>

有关 WPF 数据绑定的详细信息,请从 MS Docs 上的 Data binding overview 文章开始。

【讨论】:

    猜你喜欢
    • 2014-07-03
    • 2020-05-07
    • 2010-12-03
    • 1970-01-01
    • 2020-04-05
    • 2021-11-28
    • 1970-01-01
    • 1970-01-01
    • 2017-06-02
    相关资源
    最近更新 更多