Search code examples
c#wpf

WPF text binding from variable changing in separate class/namespace


I am struggling with Text binding in my WPF app.

  1. Lets imagine that I have another working app (ex. windows service) with some data in it.
  2. In my WPF app I would like to have folder "DATA" with class where data are introduced and in same folder another class which would include a void which will query my windows service
  3. I would like to show this data in my WPF window.

To make it simpler - one class with data, one class with data changing and WPF window with showing this data.

Unfortunately I can not achieve this... When I am executing below code, my window is showing 0 instead 123.

I would like to achive that my window will show value 123.

  1. file "Database.cs" in folder "Data" in project "example"
namespace example.Data
{
    public class Database
    {
        private int _testInt = 0;

        public int testInt
        { 
            get { return _testInt; } 
            set { _testInt = value; } 
        }
    }
}
  1. file "Query.cs" in folder "Data" in project "example"
namespace example.Data
{
    public class Query
    {
        public Database _database;
        public void execute()
        {
           _database = new Database();
           _database.testInt = 123;
        }
    }
}
  1. file "MainWindow.xaml.cs" in project "example"
namespace example
{
    public partial class MainWindow : Window
    {
        public Data.Database _database;
        public Data.Query _query;

        public int testInt
        {
            get { return _database.testInt; }
            set { _database.testInt = value; OnPropertyChanged(); }
        }
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
            _database = new Data.Database();
            _query = new Data.Query();

            _query.execute();
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                var e = new PropertyChangedEventArgs(propertyName);
                handler(this, e);
            }
        }
        #endregion
    }
}
  1. File MainWindow.xaml
<Window>
<TextBlock Text="{Binding testInt}"
                       Foreground="White"
                       FontSize="15"
                       VerticalAlignment="Top"
                       HorizontalAlignment="Left"
                       Margin="20,10,10,0" />
</Window>

P.S. If I will put

_database.testInt = 987;

to MainWindow.xaml.cs it is working properly - window is showing value 987 in textblock.


Solution

  • You have multiple instances of the Database object, a new one each time Query.execute is called and one in MainWindow constructor.

    It's the data in the later that is displayed.

    You should modify the content of this instance to see any change, for that, you must inject it in the Query object:

    _query = new Data.Query(_database);
    
    // ...
    
    public class Query
    {
        private readonly Database _database;
    
        public Query(Database database)
        {
            _database = database;
        }
    
        public void Execute()
        {
           _database.testInt = 123;
        }
    }
    

    Finally you need a way to notify the view that the content as changed, that why Database should implement INotifyPropertyChanged.

    But at this point it's badly named, because it's a model in the MVVM pattern.