I am having a problem with binding data. I'd like to bind text of TextBox which is in MainWindow to another TextBox which is in ChildWindow. While being in MainWindow, user can input a string into that TextBox. ChildWindow will be only displaying some data. I've managed to bind the TextBox from MainWIndow and I can see that while debugging it hits MainWindowViewModel, However there's no effect on the ChildWindow.
My App.xaml.cs looks like this:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
var window = new MainWindow() { DataContext = new MainWindowViewModel() };
window.Show();
base.OnStartup(e);
}
}
then MainWIndow creates an instance of ChildWindow and they both use same ViewModel as below:
public partial class MainWindow : Window
{
public MainWindow()
{
var viewModel = new MainWindowViewModel();
ChildWindow childWindow = new ChildWindow();
childWindow.DataContext = viewModel;
childWindow.Show();
InitializeComponent();
DataContext = viewModel;
}
}
MainWindowViewModel:
public class MainWindowViewModel : ViewModelBase
{
public string _firstTeamName { get; set; }
public string FirstTeamName
{
get { return _firstTeamName; }
set
{
_firstTeamName = value;
OnPropertyChanged(nameof(FirstTeamName));
}
}
}
ViewModelBase:
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
var handler = this.PropertyChanged;
if (handler != null)
{
handler(this, e);
}
}
}
Binding in MainWindow.xaml:
<TextBox x:Name ="firstTeam" Height="30" VerticalAlignment="Top" Text ="{Binding FirstTeamName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
Binding in ChildWindow.xaml:
<TextBlock Text ="{Binding FirstTeamName}" FontSize="24"></TextBlock>
Your mistake is to set the MainWindow.DataContext
twice.
MainWindow
App.OnStartUp
with var window = new MainWindow() { DataContext = new MainWindowViewModel() };
What does happen here?
new MainWindow()
will call the constructor and set the DataContext
of MainWindow
and ChildWindow
to the same instance of MainWindowViewModel
.{ DataContext = new MainWindowViewModel() }
will overwrite the DataContext
of MainWindow
with a new instance of MainWindowViewModel
.Now the two windows have two different instances of the ViewModel and will not work as expected.
This should fix it
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
var window = new MainWindow()
{
// DataContext = new MainWindowViewModel()
};
window.Show();
base.OnStartup(e);
}
}