开发者

MvvmLight RaisePropertyChanged error in Release builds?

开发者 https://www.devze.com 2023-03-22 07:28 出处:网络
I\'ve got a weird little bug which is occurring under MvvmLight v4 (.NET 4 build, v4.0.0.0/BL0016, installed via NuGet). In my project is a view model (which inherits from ViewModelBase) that represen

I've got a weird little bug which is occurring under MvvmLight v4 (.NET 4 build, v4.0.0.0/BL0016, installed via NuGet). In my project is a view model (which inherits from ViewModelBase) that represents a visual element drawn on a canvas. This view model has typical Top/Left/Width/Height properties, each of which calls RaisePropertyChanged, e.g.

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

        _width = value;
        RaisePropertyChanged();
    }
}

In response to various events, the view model also has a method which calculates the position and dimensions of the visual element, and sets the properties appropriately:

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

I have some unit tests in place that verify that calculations are done correctly, and when I run in Debug mode, the tests run fine. However, if I run in Release mode, the tests fail, with the following exception:

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

where line 154 on TableViewModel is the Width = DoSomeCalculation() line. In other words, when my method tries to set the开发者_如何转开发 property's value, MvvmLight complains that I'm not calling RaisePropertyChanged from within a property setter. I've tried debugging the test (using Reshaper's test debugger), but when I run the debugger, the test passes (maybe debugging a unit test in Resharper forces it into Debug mode, even if in Release mode already?) The error also occurs in the application itself.

Any ideas as to why Release mode would break the code? Is there something in the way the compiler optimises code that breaks the use of the StackTrace in ObservableObject's RaisePropertyChanged() method? Note that the exception above doesn't show the Width setter being entered, it jumps straight from the CalculateSize method to the exception.


If you look at the MVVM Light code you can see that RaisePropertyChanged() uses a StackTrace to determine the name of the property. This can be a problem in release mode as described in this post.

Use a different RaisePropertyMethod to circumnavigate this problem - you can use one of the following methods:

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

or

RaisePropertyChanged("Width");

Both methods use a different method to determine the name of the property that has changed (the second just uses the property name).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号