birni
birni

Reputation: 9

Data Context can´t find object

im rather new to wpf and trying to code a minesweeper game as exercise. My problem is that i cant get the datacontext of my Stackpanel to find the object row unless i set the datacontext for the whole window to the RowUpper class as seen in the code below. Tried it with the row object as field of RowUpper class or as normal object in the MainWindow class. I want to provide the textbox ZeitAnzeigeTB with the value of the timeShown field to be able to show a counter.

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();
        }
    }
}

Upvotes: 0

Views: 1114

Answers (1)

Clemens
Clemens

Reputation: 128060

The expression

DataContext="{Binding row}"

would only work of there would be a public property row in the current DataContext, which is apparently not the case.

Setting DataContexts like you do in XAML is not how data binding works.

In the most simple case, you would have this constructor:

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

and bind properties of UI elements to properties of the RowUpper object in the current DataContext like

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

For details about WPF data binding, start with the Data binding overview article on MS Docs.

Upvotes: 3

Related Questions