I'm just getting started with WPF in C#, currently using Visual Studio 2019, WPF application in .NET Framework 4.7.2.
I've been struggling with data binding for a few days now, going through numerous tutorials and websites, trying to figure out what I'm missing. At this point, I have placed my current project on hold and started a fresh, new WPF .NET Framework application (no MVVM or any other add-in packages, just C# and WPF XAML) to see if I can get this sorted out, and I am not having any luck.
For the life of me, I cannot get a single public variable that is declared in the MainWindow.xaml.cs file to be bindable in the XAML file. If, for example, I add a public string property (TestString) to the CS file, with a getter and setter, it does not show up when I try to set a textbox Binding to it, whether I use Binding TestString, or Binding Path=TestString, it always shows "No DataContext found for Binding 'TestString', and it has been this way for every other type and control I have tried.
I have tried adding "this.DataContext = this;" to the MainWindow CS file's constructor, and that makes no difference, the binding does not occur when the program is running either. Something I had noticed in other tutorial videos is that when people add the binding statements to the controls, they have intellisense showing the available options, but I have never seen that, the only intellisense I get when adding a Binging to a textbox, or any other type of control, is a list of things like AsyncState, BindingGroupName, BindsDirectlyToSource, Converter, ConverterCulture, and so on. If I select Path from those options, there is no intellisense for any available public properties in the code-behind file.
Below is what I have in the XAML:
<Window x:Class="WPFTest.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:WPFTest"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="20"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Path=TestString}"></TextBox>
</Grid>
</Window>
And this is what I have in the MainWindow.xaml.cs file:
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Forms;
namespace WPFTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : INotifyPropertyChanged
{
private string _testString;
public string TestString
{
get
{
return _testString;
}
set
{
_testString = value;
OnPropertyChanged();
MessageBox.Show(_testString);
}
}
public MainWindow()
{
DataContext = this;
InitializeComponent();
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
}
I added a message box to the setter of the TestString just to see if it was ever getting set, and it is not. The program compiles and runs, but the binding does not occur. In my main project, which has a GridView, the only way I can get it to show the data from the C# collection is if I force it into the GridView from the code behind file.
Any help you can provide would be greatly appreciated.