调用 SetProperty 时未触发 OnPropertyChanged [英] OnPropertyChanged not fired when SetProperty is called

查看:102
本文介绍了调用 SetProperty 时未触发 OnPropertyChanged的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Prism 5 和 Visual Basic,但我想 C# 中的解决方案也适用于我.

I am using Prism 5 and Visual Basic, but I guess a solution in C# would be also valid for me.

我的问题是这段代码工作正常:

The problem I have is that this code works fine:

Private Property _nombreEnvio As String
Public Property nombreEnvio As String
    Get
        Return _nombreEnvio
    End Get
    Set(value As String)
        SetProperty(_nombreEnvio, value)
        OnPropertyChanged("nombreEnvio")
    End Set
End Property

但如果我删除调用 OnPropertyChange 的行,它不会更新视图中的字段:

But if I remove the line that calls OnPropertyChange, it does not update the fields in the view:

Private Property _nombreEnvio As String
Public Property nombreEnvio As String
    Get
        Return _nombreEnvio
    End Get
    Set(value As String)
        SetProperty(_nombreEnvio, value)
        ' THIS CODE DOES NOT REFRESH THE VIEW
    End Set
End Property

应该是 SetProperty 调用应该调用 OnPropertyChanged,但它没有.它有一个奇怪的行为,它用最后一个值更新视图.我自己解释,因为它很复杂:

It is supposed that the SetProperty call should call the OnPropertyChanged, but it does not. It has a strange behaviour where it updates the view with the last value. And I explan myself, because it is complicated:

  • 如果 nombreEnvio 是 CARLOS,并且我将其设置为 PEDRO,它不会更新视图,它仍然显示 CARLOS.
  • 如果我将其设置为 ANTONIO,它会在视图中显示 PEDRO
  • 如果我将其设置为 MIGUEL,那么它会在视图中显示 ANTONIO
  • 依此类推...始终是最后一个值,而不是现在设置的值

只需添加 OnPropertyChanged 行,它就可以正常工作.

And just adding the OnPropertyChanged line, it works fine.

谁能解释一下为什么会这样?

Can anyone explain me why could it be?

非常感谢

2015 年 1 月 30 日更新我创建了一个新的 VB 项目(名为 TestPrismVB),安装了 Prism 并编写了这个简单的代码:

UPDATED 30/01/2015 I have created a new VB project (named TestPrismVB), installed Prism and I have written this simple code:

Imports Microsoft.Practices.Prism.Mvvm

Public Class pruebaViewModel
    Inherits BindableBase

    Private Property _oneProperty As String
    Public Property oneProperty As String
        Get
            Return _oneProperty
        End Get
        Set(value As String)
            SetProperty(_oneProperty, value)
            'IF I UNCOMMENT THIS LINE, IT WORKS:
            'OnPropertyChanged("oneProperty")
        End Set
    End Property

    Private Property _anotherProperty As String
    Public Property anotherProperty As String
        Get
            Return _anotherProperty
        End Get
        Set(value As String)
            SetProperty(_anotherProperty, value)
            oneProperty = value
        End Set
    End Property
End Class

XAML 文件是 MainWindow.xaml:

And the XAML file is MainWindow.xaml:

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vm="clr-namespace:TestPrismVB"
    Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <vm:pruebaViewModel/>
    </Window.DataContext>
    <StackPanel>
        <TextBox Text="{Binding anotherProperty, UpdateSourceTrigger=PropertyChanged}"/>
        <TextBlock Text ="{Binding oneProperty}"/>
    </StackPanel>
</Window>

如果您运行这个简单的项目,并输入 1234,您将看到 TextBlock 更新了一步(它将显示 123 而不是 1234).

If you run this simple project, and you type 1234, you will see that the TextBlock updates one step behind (it will show 123 instead of 1234).

这是一个 VB 错误吗?棱镜错误?我做错了什么吗?

Is it a VB bug? A Prism bug? Am I doing something wrong?

谢谢

推荐答案

好吧,我现在可以帮你了.我不是 Visual Basic 开发人员,所以我没有在您的代码中看到错误",但是经验丰富的 VB.NET 专家可以在 5 分钟内为您提供帮助.

Well, I can help you now. I'm not a Visual Basic developer, so I didn't see the "error" in your code, but an experienced VB.NET specialist could help you in 5 minutes.

所以 Prism 和 Visual Basic 完全按照它们应该做的来做所有事情,问题是由您的代码引起的,这一行对此负责:

So Prism and Visual Basic do all the things exactly as they should do, the issue is caused by your code, and this line is responsible for it:

Private Property _oneProperty As String

SetProperty() 方法接受属性存储 ByRef,但您提供一个 属性 作为存储.在这种情况下,当您将 属性 作为 ByRef 参数传递时,VB 会将属性值复制到一个临时变量中,将该变量 ByRef 并将变量中的值赋回给属性.

The SetProperty() method accepts the property storage ByRef, but you provide a property as a storage. In this case, when you pass a property as a ByRef parameter, VB copies the property value to a temporary variable, passes the variable ByRef and assigns back the value in the variable to the property.

观察到的行为有一个简单的解释:Prism 引发 PropertyChanged 事件并且 WPF 绑定请求新的属性值就在之前它将由 VB 从临时变量分配已实际通过ByRef.

The observed behavior has a simple explanation: Prism raises the PropertyChanged event and WPF binding requests the new property value just before it will be assigned by VB from the temporary variable which has been actually passed ByRef.

TL;DR 解决方案是:

替换这个

Private Property _oneProperty As String
Private Property _anotherProperty As String

有了这个

Private _oneProperty As String
Private _anotherProperty As String

这篇关于调用 SetProperty 时未触发 OnPropertyChanged的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆