PropertyChangedEventHandler在silverlight绑定中始终为null

时间:2010-09-22 12:10:28

标签: silverlight data-binding xaml

我一直试图解决这个问题。 我正在尝试使用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));
        }
    }


}

2 个答案:

答案 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。