发布版本中的MvvmLight RaisePropertyChanged错误?

时间:2011-07-21 02:56:43

标签: mvvm-light

我有一个奇怪的小错误,发生在MvvmLight v4(.NET 4 build,v4.0.0.0 / BL0016,通过NuGet安装)下。在我的项目中是一个视图模型(继承自ViewModelBase),它表示在画布上绘制的可视元素。此视图模型具有典型的Top / Left / Width / Height属性,每个属性都调用RaisePropertyChanged,例如

public double Width
{
    get { return _width; }
    set
    {
        if (Math.Abs(_width - value) < DeltaEpsilon)
        {
            return;
        }

        _width = value;
        RaisePropertyChanged();
    }
}

为了响应各种事件,视图模型还有一个计算视觉元素的位置和尺寸的方法,并适当地设置属性:

public void CalculateSize()
{
    Width = DoSomeCalculation();
    // Calculate other settings...
}

我有一些单元测试可以验证计算是否正确完成,当我在调试模式下运行时,测试运行正常。但是,如果我在发布模式下运行,测试将失败,但会出现以下异常:

SetUp : System.InvalidOperationException : This method can only by invoked within a property setter.
at GalaSoft.MvvmLight.ObservableObject.RaisePropertyChanged()
at MyProject.ViewModels.TableViewModel.CalculateSize() in TableViewModel.cs: line 154

TableViewModel上的第154行是Width = DoSomeCalculation()行。换句话说,当我的方法试图设置属性的值时,MvvmLight抱怨我没有在属性设置器中调用RaisePropertyChanged。我已经尝试调试测试(使用Reshaper的测试调试器),但是当我运行调试器时,测试通过(可能在Resharper中调试单元测试强制它进入调试模式,即使在Release模式下已经?)也会发生错误在应用程序本身。

关于为什么发布模式会破坏代码的任何想法?编译器是否优化了在ObservableObject的RaisePropertyChanged()方法中打破StackTrace使用的代码?请注意,上面的例外不会显示正在输入的宽度设置器,它会直接从CalculateSize方法跳转到异常。

1 个答案:

答案 0 :(得分:3)

如果查看MVVM Light代码,可以看到RaisePropertyChanged()使用StackTrace来确定属性的名称。如this post中所述,这可能是发布模式中的问题。

使用其他RaisePropertyMethod来绕过此问题 - 您可以使用以下方法之一:

RaisePropertyChanged<YourClass>(x => x.Width);

RaisePropertyChanged("Width");

两种方法都使用不同的方法来确定已更改的属性的名称(第二种方法仅使用属性名称)。