【问题标题】:PropertyChangedEventHandler always null in silverlight bindingSilverlight 绑定中的 PropertyChangedEventHandler 始终为空
【发布时间】:2010-09-22 12:10:28
【问题描述】:

一段时间以来,我一直在尝试解决此问题。 我正在尝试使用 INotifyPropertyChanged 接口将 TextBlock 的文本绑定到字符串属性。由于某种原因,当属性的值发生更改时,PropertyChangedEventHandler 始终为空,因此目标永远不会更新...... 有什么建议么? 代码如下:

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));
        }
    }


}

【问题讨论】:

    标签: silverlight data-binding xaml


    【解决方案1】:

    这是基于提供的 cmets 而不仅仅是上面的问题。

    基本上,问题在于您正在创建更新 ViewModel 的第二个实例(在您的代码中称为 YearScreen)并更新它。

    已经创建了一个 YearScreen 并将其绑定到您的 Xaml,其中包含:

    <UserControl.Resources>
        <prop:YearScreen x:Key="YearScreenProps"/>
    </UserControl.Resource>
    

    然后,您将在代码的其他位置(通过 new ViewScreen())创建第二个 ViewScreen 并对其进行更新,但是这两个 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。

    【讨论】:

    • 那是我在摆弄,我把它改成了“YearProperty”但还是没有!
    • @SilverlightNewbie:您如何更改 ViewModel 的特定实例的 YearProperty 值?
    • yearScreen = new YearScreen();然后我有一个组合可以像这样设置 YearProperty:yearScreen.YearProperty = this.CmbBxYearSelector.SelectedItem.ToString();
    • @SilverlightNewbie:所以基本上你是在代码中创建第二个 YearScreen,与在视图 XAML 中为你创建的屏幕完全断开并设置它的属性...和期望附加到视图的更新。这永远不会起作用,因为它们是单独的实例。我会尽快更新答案以提供建议。
    • @HiTech Magic:是的,看起来像,我从来不知道如何(以及在​​哪里)设置属性值......
    【解决方案2】:

    您应该从外部代码将其设置到视图的 DataContext 中,而不是在资源中创建 ViewModel。

    如果你真的想把它放在 Resources 中,你可以在 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"];
    }
    

    也许将其作为属性公开,以便您可以在外部访问它。但就我个人而言,我宁愿在外部创建模型,也不愿将其传递给视图。将其放入 DataContext 中。

    【讨论】:

    • 以防万一:如果我在页面上只有一个模型,那就行了...问题是我在这个阶段真的在进行原型设计和尝试...我发现的是我可以做 YearScreen yearScreen=this.Resources["YearScreenProps"] 然后设置值。还是谢谢你的回复
    • 为什么拥有多个模型会改变事情?您只需将它们放入集合或父对象中,然后将其绑定到页面的根目录。
    猜你喜欢
    • 2011-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-25
    • 2011-04-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多