我一直试图解决这个问题。 我正在尝试使用INotifyPropertyChanged接口将TextBlock的文本绑定到字符串属性。由于某种原因,当属性的值发生更改时,PropertyChangedEventHandler始终为null,因此目标永远不会更新... 有什么建议? 代码如下:
XAML代码:
<UserControl x:Class="MoleDashboard.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:basics="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
xmlns:datacontrols="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
xmlns:primitives="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls.Data"
xmlns:prop="clr-namespace:MoleDashboard"
<UserControl.Resources>
<prop:YearScreen x:Key="YearScreenProps"/>
</UserControl.Resource>
<TextBlock Margin="10 5" x:Name="DataGridLabel" Visibility="Visible" Text="{Binding YearProperty, Source={StaticResource YearScreenProps}, Mode=OneWay}"/>
绑定属性代码:
public class YearScreen : INotifyPropertyChanged
{
private string metricProperty;
private string yearProperty;
public event PropertyChangedEventHandler PropertyChanged;
public YearScreen()
{
}
public string YearProperty
{
get { return yearProperty; }
set { yearProperty = value; this.OnPropertyChanged("YearProperty"); }
}
public string MetricProperty
{
get { return metricProperty; }
set { metricProperty = value; this.OnPropertyChanged("MetricProperty"); }
}
public void OnPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
答案 0 :(得分:2)
这取决于所提供的评论,而不仅仅是上述问题。
基本上问题是您正在创建更新ViewModel的第二个实例(在代码中称为YearScreen)并更新它。
已经创建了YearScreen并将其绑定到您的Xaml,包括:
<UserControl.Resources>
<prop:YearScreen x:Key="YearScreenProps"/>
</UserControl.Resource>
然后您在代码中的其他位置创建第二个ViewScreen(通过新的ViewScreen())并更新它,但是2个ViewScreen实例之间没有连接,因此Xaml页面中不会更新任何内容。
将YearScreen创建为单身人士。这是在类中添加类型为YearScreen的静态访问器,并从构造函数中设置它。
public class YearScreen : INotifyPropertyChanged
{
private static YearScreen _This;
public static YearScreen This { get { return _This; } }
[snip]
public YearScreen()
{
_This = this;
}
您可以使用静态单例访问器从其他地方访问YearScreen的“单个”实例,例如:
YearScreen.This.YearProperty = DateTime.Now.ToString():
与单身人士共享ViewModel有更好的模式,但这会让你前进。
您开始使用的模式是 ViewFirst 创建(视图创建ViewModel)。 ModelFirst 执行相反的操作,但由于模型知道它是如何显示的。使用控制器对象来创建View和ViewModel并连接它们是一个更好的选择,但这会变得非常复杂。使用单实例对象的注入是一个更好的选择,但涉及一大堆新概念。在解决当前问题后查找Silverlight Prism。
答案 1 :(得分:0)
您应该在外部代码中将其设置为视图的DataContext,而不是在资源中创建ViewModel。
如果你真的想把它放在资源中,那么你可以从在Loaded方法后面的代码中的资源或者在initializecomponent调用之后的构造函数中获取它。像这样:
private YearScreen model;
public MainPage()
{
this.Loaded += MainPage_Loaded;
this.InitializeComponent();
}
void MainPage_Loaded(object sender, EventArgs e)
{
this.model = (YearScreen)this.Resources["YearScreenProps"];
}
可能将其作为属性公开,以便您可以在外部访问它。但就我个人而言,我宁愿在外部创建模型而不是将其传递给View。将它放入DataContext。