3

ドキュメントによると、「(FrameworkElement.SizeChanged) ActualHeight または ActualWidth プロパティのいずれかがこの要素の値を変更したときに発生します。」

次のテスト メソッドを実行すると、Measure と Arrange を呼び出した後に Rectangle の ActualWidth と ActualHeight が更新されますが、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 が発生しない理由を説明できる人はいますか?
上げるように設定する方法はありますか?


解決

HB の静的クラスでスリップすると、このテストはパスします。

   [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);
        }
    }
4

2 に答える 2

4

長方形は、キューに入れられた方法で処理を行う UI スレッドによって管理されます。SizeChanged完全なメソッドが実行されてからずっと後に起動します。ブレークポイントを設定するか、bool を設定する代わりに MessageBox を表示すると、実際にそうであることがわかります。解雇されています。

編集:どのようにテストしますか。事前に遅延を追加するだけです:

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);
    }
}
于 2011-07-27T22:37:38.357 に答える