英文:
WPF using one VIewModel to manipulate TextBoxes in two seperate windows
问题
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 the 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>
英文:
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>
答案1
得分: 0
你的错误是将 MainWindow.DataContext
设置了两次。
- 在
MainWindow
构造函数内。 - 在
App.OnStartUp
中使用var window = new MainWindow() { DataContext = new MainWindowViewModel() };
。
这里发生了什么?
new MainWindow()
会调用构造函数并将MainWindow
和ChildWindow
的DataContext
设置为相同的MainWindowViewModel
实例。{ DataContext = new MainWindowViewModel() }
会用一个新的MainWindowViewModel
实例覆盖MainWindow
的DataContext
。
现在这两个窗口有两个不同的 ViewModel 实例,将不会按预期工作。
这应该修复它
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
var window = new MainWindow()
{
// DataContext = new MainWindowViewModel()
};
window.Show();
base.OnStartup(e);
}
}
英文:
Your mistake is to set the MainWindow.DataContext
twice.
- Inside the contructor of
MainWindow
- In
App.OnStartUp
withvar window = new MainWindow() { DataContext = new MainWindowViewModel() };
What does happen here?
new MainWindow()
will call the constructor and set theDataContext
ofMainWindow
andChildWindow
to the same instance ofMainWindowViewModel
.{ DataContext = new MainWindowViewModel() }
will overwrite theDataContext
ofMainWindow
with a new instance ofMainWindowViewModel
.
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);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论