Модель просмотра WPF + PostSharp замерзает за минуту - PullRequest
0 голосов
/ 16 сентября 2018

ОБНОВЛЕНО (см. Ниже)

WPF начинает игнорировать уведомления об изменениях свойств после минуты интенсивной работы.Вот демонстрационная версия для воспроизведения (также на GitHub ).Модель просмотра:

[Aggregatable]
[NotifyPropertyChanged]
[ContentProperty("Tests")]
public class Model
{
    [Child] public AdvisableCollection<Test> Tests { get; } = new AdvisableCollection<Test>();
    [Child] public Test Test { get; set; }
}

Где:

[Aggregatable]
[NotifyPropertyChanged]
public class Test
{
    public string Name { get; set; }
    [Parent] public Model Model { get; private set; }
}

XAML:

<Window x:Class="Demo.MainWindow"
        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:local="clr-namespace:Demo"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:Model>
            <local:Test Name="a"/>
            <local:Test Name="b"/>
            <local:Test Name="c"/>
            <local:Test Name="d"/>
        </local:Model>
    </Window.DataContext>
    <TextBox DockPanel.Dock="Top" Text="{Binding Test.Name, Mode=OneWay}"/>
</Window>

И код позади:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        Timer = new DispatcherTimer();
        Timer.Interval = TimeSpan.FromMilliseconds(250);
        Timer.Tick += Timer_Tick;
        Timer.Start();
    }

    DispatcherTimer Timer { get; }
    Random Random = new Random();
    Model Model => DataContext as Model;

    private void Timer_Tick(object sender, EventArgs e)
    {
        var i = Random.Next(Model.Tests.Count);
        Model.Test = Model.Tests[i];
    }
}

Выполнитьэто и подождите - окно замерзнет.Любые идеи, как это исправить?

ОБНОВЛЕНИЕ

Я упростил модель - эта все еще застывает в минуту:

[NotifyPropertyChanged]
[ContentProperty("Tests")]
public class Model
{
    public List<Test> Tests { get; } = new List<Test>();
    public Test Test { get; set; }
}

[NotifyPropertyChanged]
public class Test
{
    public string Name { get; set; }
}

Но следующая версия класса Test решает проблему:

public class Test : INotifyPropertyChanged
{
    public string Name { get; set; }

    public event PropertyChangedEventHandler PropertyChanged = delegate { };
}

1 Ответ

0 голосов
/ 20 сентября 2018

Похоже, что эта проблема вызвана несовместимостью между менеджером слабых событий аспекта NotifyPropertyChanged и менеджером слабых событий в WPF.В качестве обходного пути вы можете отключить реализацию слабых событий аспекта при применении аспекта к целевому элементу:

[NotifyPropertyChanged( WeakEventStrategy = WeakEventStrategy.AlwaysStrong )]
[ContentProperty("Tests")]
public class Model
{
    // ...
}

[NotifyPropertyChanged( WeakEventStrategy = WeakEventStrategy.AlwaysStrong )]
public class Test
{
    // ...
}

Мы продолжим исследовать проблему и обновим ответ, как только будет выпущено исправление.

РЕДАКТИРОВАТЬ: Эта проблема была исправлена ​​в PostSharp 6.0.28.

...