WPF ActualWidth为零

Mar*_*ark 5 .net c# wpf layout actualwidth

我有一个Canvas高度为100和宽度为1920 的用户控件.

在加载控件时,我转到外部源,下载文本文件并将TextBlocks 添加到Canvas.然后我想创建一个选框滚动效果应该可以正常工作,除非我添加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;
        }
    }));
}
Run Code Online (Sandbox Code Playgroud)

小智 5

你可以随时附加一个delgate PropertyMetatdata/OnValueChanged,当ActualHeight/ActualWidth从0变为某些东西时,调整你的滚动,ActualWidth/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
   ...
}
Run Code Online (Sandbox Code Playgroud)


Run*_*sen 3

如果您想坚持使用调度程序调用 - 将优先级设置为已加载,那么它将与已加载事件同时调用,并且您应该有一个值。BeginInvoke 上有一个重载也具有优先级。