嵌套属性propertychanged事件只在silverlight的usercontrol中触发一次

本文关键字:一次 usercontrol 事件 propertychanged 属性 silverlight 嵌套 | 更新日期: 2023-09-27 18:11:36

有两个viewmodel,它们都实现了INotifyPropertyChanged接口(我在实际代码中调用了OnpropertyChanged("propertyname"))。

    Public Class A{
        public B BProperty
        {
            get
            {
                return _BProperty;
            }
            set
            {
                if (_BProperty != null)
                    _BProperty.PropertyChanged -= _BProperty_PropertyChanged;
                _BProperty = value;
                OnPropertyChanged("BProperty");
                if (_BProperty != null)
                    _BProperty.PropertyChanged += _BProperty_PropertyChanged;
            }
        }
        void _BProperty_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "status")
            {
                OnPropertyChanged("BProperty");
            }
        }
        B _BProperty;
}

Public Class B
{
   public int status{get;set;}
}

我也有一个userControl:

<MyUserControl  ...
                ... >
   <Grid>
   </Grid>
</MyUserControl>

还有dependencyProperty:

/// <summary>
/// File status
/// </summary>
public int Filestatus
{
    get { return (int)GetValue(FilestatusProperty); }
    set { SetValue(FilestatusProperty, value); }
}
public static readonly DependencyProperty FilestatusProperty =
    DependencyProperty.Register(
    "Filestatus",
    typeof(int),
    typeof(MyUserControl),
    new PropertyMetadata(0, OnFilestatusPropertyChanged));
private static void OnFilestatusPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    MyUserControl control = (MyUserControl)d;
    if (e.NewValue != null)
    {
    }
}

编辑:2015/09/21添加get/set方法:

        public static readonly DependencyProperty FileStatusProperty = DependencyProperty.RegisterAttached(
"FileStatus", typeof(int), typeof(FileStatusIconControl), new PropertyMetadata(0, PropertyChangedCallback));
    public static int GetFileStatus(DependencyObject source)
    {
        return (int)source.GetValue(FileStatusProperty);
    }
    public static void SetFileStatus(DependencyObject target, int value)
    {
        target.SetValue(FileStatusProperty, value);
    }
    private static void PropertyChangedCallback(
        DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
    {
        FileStatusIconControl fsic = dependencyObject as FileStatusIconControl;
        if(fsic != null)
            wahahahahaha;
    }

编辑结束

我在mainPage中使用了这个userControl:

<mainPage ...
          ...>
  <Grid>
    <MyUserControl Filestatus={Binding Bproperty.status} />
    <TextBox Text={Binding Bproperty.status} />
  </Grid>
</mainPage>

mainPage的数据上下文是类a的一个实例。

我的问题是:当状态改变时,文本框的文本也会改变,但是OnFilestatusPropertyChanged方法只在Usercontrol加载时被调用一次。为什么?谢谢。

嵌套属性propertychanged事件只在silverlight的usercontrol中触发一次

我首先要说的是,当我在调查你的问题时,我遇到了你提供的代码的一些问题。我很感激你在某个地方有一些真正的代码有问题,你不能与我们分享这个代码,所以我试着在一个较小的文件集中重现这个问题。

但是,如果您这样做,请至少验证您提供的代码运行并显示问题。很明显,您没有尝试运行示例代码(特别是XAML),因为它存在问题:

  • 属性值应该用双引号括起来,
  • 绑定路径Bproperty.status应该是BProperty.status(第一个P大写)。

所有这些事情都阻碍了试图帮助你的人。更糟糕的是,当我在你的代码中发现一个问题时,我不能确定它是你的实际代码中也存在的一个真正的问题,还是你在组合你的示例代码时引入的问题。因此,我所能做的就是指出我发现的所有问题,希望其中一个问题是您在实际代码中遇到的问题。

首先,TextBoxText属性绑定不包含Mode=TwoWay。在WPF中,这个绑定默认是TwoWay,但在Silverlight中,所有绑定默认都是OneWay。如果您熟悉WPF,这可能就是省略Mode=TwoWay的原因。

其次,我不明白为什么你已经实现了类B,显然留给类A来代表它触发属性更改事件。这种方法不起作用:当Silverlight更新B实例的status属性中的值时,它通过调用B实例的status setter来实现。您的B类只有一个自动生成的属性设置器,它当然不会触发PropertyChanged事件。因为这个事件没有被触发,Silverlight不知道它有一些更新要做,而且你的A类也不知道它已经改变了。

我将在B类中以通常的方式实现INotifyPropertyChanged,通过在status setter中调用OnPropertyChanged。我还会删除A类中的BProperty_PropertyChanged事件处理程序,因为我认为它对您没有任何好处。