6

Canvas高さ100、幅1920のユーザーコントロールがあります。

コントロールのロード時に、外部ソースに移動し、テキストファイルをダウンロードTextBlockして、Canvasにsを追加します。次に、マーキースクロール効果を作成します。これは、TextBlocksをに追加した後Canvas、計算のために幅を取得する必要がありますが、ActualWidthプロパティは常にゼロです。

ここにいくつかのコードがあります:

private readonly LinkedList<TextBlock> textBlocks = new LinkedList<TextBlock>();

public LocalNewsControl()
{
    Loaded += LocalNewsControlLoaded;
}

private void LocalNewsControlLoaded(object sender, RoutedEventArgs e)
{
    LoadDataContext();
}

private void LoadDataContext()
{
    DataContext = new NewsItemsViewModel((exception) => LoadNewsItems());
}

private void LoadNewsItems()
{
    var viewModel = (NewsItemsViewModel)DataContext;

    NewsCanvas.Children.Clear();
    textBlocks.Clear();

    foreach (var newsViewModel in viewModel.NewsItems)
    {
        var tb = new TextBlock
        {
            Text = newsViewModel.Headline,
            FontSize = 28,
            FontWeight = FontWeights.Normal,
            Foreground = Brushes.Black
        };

        NewsCanvas.Children.Add(tb);

        Canvas.SetTop(tb, 20);
        Canvas.SetLeft(tb, -999);

        textBlocks.AddLast(tb);
    }

    Dispatcher.BeginInvoke(new Action(() =>
    {
        var node = textBlocks.First;

        while (node != null)
        {
            if (node.Previous != null)
            {
                //THIS IS WHERE ActualWidth is always ZERO
                var left = Canvas.GetLeft(node.Previous.Value) + node.Previous.Value.ActualWidth + Gap;
                Canvas.SetLeft(node.Value, left);
            }
            else
                Canvas.SetLeft(node.Value, NewsCanvas.Width + Gap);

            node = node.Next;
        }
    }));
}
4

4 に答える 4

5

常にデリゲートをアタッチすることができ、0 から何かに変化しPropertyMetatdata/OnValueChangedたときにスクロールを調整すると、少なくとも 1 回レンダリングされると値が得られます。ActualHeight/ActualWidthActualWidth/ActualHeight

LocalNewsControl()
{
    var descriptor = DependencyPropertyDescriptor.FromProperty(ActualWidthProperty, typeof(TextBlock));
    if (descriptor != null)
        descriptor.AddValueChanged(myTextBlock, ActualWidth_ValueChanged);
}

private void ActualWidth_ValueChanged(object a_sender, EventArgs a_e)
{
   //Modify you scroll things here
   ...
}
于 2010-12-21T12:04:45.727 に答える
3

ディスパッチャー呼び出しを使い続けたい場合は、優先度をロード済みに設定すると、ロード済みイベントと同時に呼び出され、値が必要です。BeginInvoke にも優先順位を持つオーバーロードがあります。

于 2010-12-21T11:44:55.277 に答える
2

orは、Control>>>になる前に常にゼロになります。ActualHeightActualWidthLoadedMeasuredArrangedRendered

あなたの場合、それを有利に使用することをお勧めLoadedSizeChangedますTextBlock

于 2010-12-21T10:52:33.893 に答える
0

Canvasのレイアウトに使用する特定の理由はありますTextBlockか? そうでない場合は、StackPanel水平方向を使用することをお勧めします。レイアウトの計算が処理されます。

于 2010-12-21T11:07:32.363 に答える