我正在尝试为练习创建一个非常简单的数据绑定应用程序,但我无法让它工作,我看了很多不同的解决方案,但没有一个帮助,我无法弄清楚问题
MainWindow.xaml:
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<Grid>
<TextBlock Text="{Binding BindText, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
Window1.xaml:
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<Grid>
<TextBox Text="{Binding BindText, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
视图模型:
using System.ComponentModel;
namespace bindtest
{
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string bindText = "Hello";
public string BindText
{
get { return bindText; }
set
{
bindText = value;
OnPropertyChanged("BindText");
}
}
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
文本首次加载时会正确显示,但不会更新。 MainWindow中的文本用于在window1中的文本更改时进行更新。 有解决方案吗 感谢
答案 0 :(得分:2)
正如JanDotNet建议的那样,您需要使用视图模型的单个实例。因此,在您的应用级代码中,您可以执行以下操作:
public partial class App : Application
{
private void App_Startup(object sender, StartupEventArgs e)
{
try
{
ViewModel vm = new ViewModel();
MainWindow w = new MainWindow(vm);
Window1 w1 = new Window1(vm);
w.Show();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
然后你的窗口构造函数修改如下:
public partial class MainWindow : Window
{
pulic MainWindow(ViewModel vm)
{
InitializeComponent();
DataContext = vm;
}
}
答案 1 :(得分:1)
由于您是通过以下方式创建视图模型的:
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
您有2个不同的视图模型实例。您必须将视图模型的相同实例绑定到视图。
如何针对2个视图绑定同一个实例?
在您的情况下,最简单的方法是创建一个单身人士:
public class ViewModel : INotifyPropertyChanged
{
public ViewModel Instance {get; } = new ViewModel();
// ....
}
并绑定到它:
<Window DataContext="{Binding Source={x:Static local:ViewModel.Instance}}" /* ... */>
请注意,这不是最佳方式....
您应该使用PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
或
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName)
确保在检查null和调用事件处理程序之间没有取消订阅处理程序!