Почему FrameworkElement.SizeChanged не вызывается в этом коде - PullRequest
2 голосов
/ 28 июля 2011

Согласно документации "(FrameworkElement.SizeChanged) Происходит, когда свойства ActualHeight или ActualWidth изменяют значение этого элемента."

При выполнении следующего метода тестирования значения ActualWidth и ActualHeight моего Rectangle обновляются после вызова Measure and Arrange, однако метод SizeChanged RoutedEvent никогда не вызывается.

    [Test]
    [RequiresSTA]
    public void Test_Something()
    {
        bool sizeChangedRaised = false;

        var r = new Rectangle { Width = 10, Height = 10 };
        r.Measure(new Size(20, 20));
        r.Arrange(new Rect(0, 0, 20, 20));

        //r.ActualWidth and r.ActualHeight are both 10 at this point.

        r.SizeChanged += (s, e) => sizeChangedRaised = true;

        r.Width = 5;
        r.Height = 5;
        r.Measure(new Size(20, 20));
        r.Arrange(new Rect(0, 0, 20, 20));

        //r.ActualWidth and r.ActualHeight are now both 5.

        Assert.That(sizeChangedRaised);// false
    }

Может кто-нибудь объяснить, почему SizeChanged не подняли?
Есть ли способ, которым я могу настроить вещи так, чтобы они поднимались?


РЕШЕНИЕ

Проскальзывание в статическом классе H.B., этот тест проходит:

   [Test]
    [RequiresSTA]
    public void Test_Something()
    {
        bool sizeChangedRaised = false;
        var r = new Rectangle { Width = 10, Height = 10 };
        r.Measure(new Size(20, 20));
        r.Arrange(new Rect(0, 0, 20, 20));
        r.SizeChanged += (s, e) => {
            sizeChangedRaised = true;
        };
        r.Width = 5;
        r.Height = 5;
        r.Measure(new Size(20, 20));
        r.Arrange(new Rect(0, 0, 20, 20));
        ThreadEx.Wait(1000);
        Assert.That(sizeChangedRaised);

    }

    static class ThreadEx
    {
        public static void Wait(int millisecondsTimeout)
        {
            Wait(TimeSpan.FromMilliseconds(millisecondsTimeout));
        }

        public static void Wait(TimeSpan timeout)
        {
            var frame = new DispatcherFrame();
            new Thread(() =>
                           {
                               Thread.Sleep(timeout);
                               frame.Continue = false;
                           }).Start();
            Dispatcher.PushFrame(frame);
        }
    }

1 Ответ

3 голосов
/ 28 июля 2011

Прямоугольник управляется UI-потоком, который делает все в порядке очереди, SizeChanged срабатывает задолго после того, как завершен метод, если вы просто устанавливаете точку останова или показывает MessageBox вместо установки bool увидит, что его действительно увольняют.

Редактировать: Как бы я его протестировал; просто добавьте задержку заранее:

ThreadEx.Wait(1000);
Assert.That(sizeChangedRaised);
static class ThreadEx
{
    public static void Wait(int millisecondsTimeout)
    {
        Wait(TimeSpan.FromMilliseconds(millisecondsTimeout));
    }

    public static void Wait(TimeSpan timeout)
    {
        var frame = new DispatcherFrame();
        new Thread((ThreadStart)(() =>
        {
            Thread.Sleep(timeout);
            frame.Continue = false;
        })).Start();
        Dispatcher.PushFrame(frame);
    }
}
...