Question

I'm making a basic program where a label updates when the user types in a text box. i'm trying to use data binding and INotifyPropertyChanged to work this out, so i don't want any workarounds. i used 2 buttons so i can actually see if they updated. here's my main class

namespace TestStringChangeFromAnotherClass

public partial class MainWindow : Window
{

    textClass someTextClass = new textClass();
    public MainWindow()
    {

        InitializeComponent();

    }

    public string someString1;
    public string someString2;

    private void btn1_Click(object sender, RoutedEventArgs e)
    {
        someTextClass.Text1 = tbx1.Text;
    }

    private void btn2_Click(object sender, RoutedEventArgs e)
    {
        someTextClass.Text2 = tbx1.Text;
    }
}

here's the wpf for it

<Window x:Class="TestStringChangeFromAnotherClass.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    DataContext="{Binding RelativeSource={RelativeSource Self}}"
    Title="MainWindow" Height="350" Width="525">

    <Grid>
    <Button x:Name="btn1" Content="Button" HorizontalAlignment="Left" Height="36" Margin="29,246,0,0" VerticalAlignment="Top" Width="108" Click="btn1_Click"/>
    <Button x:Name="btn2" Content="Button" HorizontalAlignment="Left" Height="36" Margin="227,246,0,0" VerticalAlignment="Top" Width="124" Click="btn2_Click"/>
    <Label x:Name="lbl1" Content="{Binding textClass.Text1}" HorizontalAlignment="Left" Height="37" Margin="74,32,0,0" VerticalAlignment="Top" Width="153"/>
    <Label x:Name="lbl2" Content="{Binding textClass.Text2, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Height="38" Margin="74,90,0,0" VerticalAlignment="Top" Width="153"/>
    <TextBox x:Name="tbx1" HorizontalAlignment="Left" Height="37" Margin="290,32,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="190"/>

</Grid>

as you can see, i've tried using UpdateSourceTrigger. i've also tried to use "someTestClass.Text1" instead of textClass.Test1, because that's how i defined it in the MainWindow. Here's my textClass

namespace TestStringChangeFromAnotherClass
public class textClass:INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private string text1;
    public string Text1
    {
        get { return text1; }
        set
        {
            text1 = value;
            NotifyPropertyChanged("Text1");
        }
    }

    private string text2;
    public string Text2
    {
        get { return text2; }
        set
        {
            text2 = value;
            NotifyPropertyChanged("Text2");
        }
    }

    protected void NotifyPropertyChanged(string info)
    {

        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(info));
    }
}

i can't figure out how to get wpf to look for the Test1 or Test2 strings in the separate class and update them when the strings change. i have a feeling the problem lies within DataContext, but i can't figure it out. i'd also rather not use DataContext within c#, only in WPF

UPDATE: when i debug this, when it gets to NotifyPropertyChanged, PropertyChanged is evaluated as null. could that be the problem?

Was it helpful?

Solution

You bind DataContext to your Window which, as far as I can see, doesn't have textClass property. It has someTextClass field of textClass type. In order for your code to work your can change someTextClass to public property:

public textClass someTextClass { get; private set; }

initialize it in constructor:

public MainWindow()
{
    someTextClass = new textClass();
    InitializeComponent();

}

and then change binding to point to someTextClass property

<Label x:Name="lbl1" Content="{Binding someTextClass.Text1}" .../>
<Label x:Name="lbl2" Content="{Binding someTextClass.Text2}" .../>

OTHER TIPS

You are binding to the MainWindow class itself as your DataContext, and trying to access the property called someTextClass that has the properties you want to bind to.

You are running into two problems:

1) Your XAML is trying to reference the desired object by it's type, not it's name. Not going to work. Your binding expressions should look like {Binding someTextClass.Text1} (note the difference in the first part of the path expression).

2) You can only bind to public things. Your field is not defined as public, and therefore is private. Even though the XAML should logically "be able to see" the property, as it's the same class, DataBinding will only work on public properties.

3) EDIT: You must also make this a property. WPF will not bind to fields.

In general, using Snoop will help diagnose silent binding errors.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top