首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >加快文本布局

加快文本布局
EN

Code Review用户
提问于 2017-12-04 09:11:21
回答 1查看 145关注 0票数 1

我创建了一个加载文本的控件,其中包含richtextblock和richtextblock溢出。控制不是很快,事实上,我想要加快的是LoadText方法。这是可能的吗?

MainPage.xaml:

代码语言:javascript
复制
<Page
x:Class="Load_All_Text_UWP.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Load_All_Text_UWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<Page.DataContext>
    <local:ColumnWidthClass x:Name="ViewModel"/>
</Page.DataContext>

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid x:Name="Menù" HorizontalAlignment="Left" Width="290" Padding="0" Margin="0,21,0,0">
        <Grid Background="White">
            <Grid.RowDefinitions>
                <RowDefinition Height="50"/>
                <RowDefinition Height="50"/>
                <RowDefinition Height="50"/>
                <RowDefinition Height="50"/>
            </Grid.RowDefinitions>
            <Button  Grid.Row="0" x:Name="btnLoadText" Click="btnLoadText_Click" Content="Text Display" HorizontalAlignment="Center" VerticalAlignment="Center" Width="270" Foreground="White" Height="32"/>
            <Grid Grid.Row="1">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <Button Grid.Column="0" x:Name="btnDecFont" Content="Aa-" HorizontalAlignment="Stretch" Click="btnDecFont_Click" Margin="10" Foreground="White"/>
                <Button Grid.Column="1" x:Name="btnIncFont" Content="aA+" HorizontalAlignment="Stretch" Click="btnIncFont_Click" Margin="10" Foreground="White"/>
            </Grid>
            <Grid Grid.Row="2">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <Button Grid.Column="0" x:Name="btnBack" Content="Back" HorizontalAlignment="Stretch" Click="btnBack_Click" Margin="10" Foreground="White"/>
                <Button Grid.Column="1" x:Name="btnForward" Content="Forward" HorizontalAlignment="Stretch" Click="btnForward_Click" Margin="10" Foreground="White"/>
            </Grid>
        </Grid>
    </Grid>
    <Grid x:Name="BaseGrid" Margin="320,10,30,10" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Black">
        <ScrollViewer x:Name="PageViewer" SizeChanged="PageViewer_SizeChanged" Background="White" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Hidden" VerticalScrollMode="Disabled" HorizontalScrollMode="Enabled">
            <StackPanel x:Name="StackViewer" Orientation="Horizontal"/>
        </ScrollViewer>
    </Grid>
</Grid>

MainPage.xaml.cs:

代码语言:javascript
复制
public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();

        timerSize.Interval = TimeSpan.FromMilliseconds(50);
        timerSize.Tick += timerSize_tick;

        timerFoBA.Interval = TimeSpan.FromMilliseconds(400);
        timerFoBA.Tick += timerFoBA_tick;

        StackViewer.Children.Add(TextOneRich);
        TextOneRich.Width = ViewModel.ColumnWidthInt;
        TextOneRich.TextAlignment = TextAlignment.Justify;
        binding = new Binding() { Path = new PropertyPath("ColumnWidthInt"), Source = ViewModel, Mode = BindingMode.OneWay };
        BindingOperations.SetBinding(TextOneRich, WidthProperty, binding);

        ViewModel.ColumnWidthInt = 400;
    }

    RichTextBlock TextOneRich = new RichTextBlock() { Margin = new Thickness(20) };
    List<RichTextBlockOverflow> TextList = new List<RichTextBlockOverflow>();
    DispatcherTimer timerSize = new DispatcherTimer();
    DispatcherTimer timerFoBA = new DispatcherTimer();
    Binding binding = new Binding();
    int numCol;
    bool TextLoaded = false;

    private async void timerSize_tick(object sender, object e)
    {
        await Task.Run(async () =>
        {
            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
            {
                timerSize.Stop();
                List<int> ChildrenList = new List<int>();
                ChildrenList.Clear();
                ChildrenList.Add(StackViewer.Children.Count - 1);

                for (int a = 0; a <= ChildrenList[0]; a++)
                {
                    if (a == 0)
                    {
                        RichTextBlock TextOne = StackViewer.Children[a] as RichTextBlock;
                        if (!TextOne.HasOverflowContent && a < ChildrenList[0])
                        {
                            for (int b = a + 1; b <= ChildrenList[0]; b++)
                            {
                                StackViewer.Children.RemoveAt(a + 1);
                                TextList.RemoveAt(a);
                            }
                            return;
                        }
                        else if (TextOne.HasOverflowContent && a == ChildrenList[0])
                        {
                            bool ThereIsText = true;
                            while (ThereIsText)
                            {
                                await Task.Delay(20);
                                if (TextList.Count == 0)
                                {
                                    await Task.Delay(20);
                                    if (TextOne.HasOverflowContent)
                                    {
                                        TextList.Add(new RichTextBlockOverflow() { Width = ViewModel.ColumnWidthInt, Margin = new Thickness(20) });
                                        StackViewer.Children.Add(TextList[TextList.Count - 1]);
                                        BindingOperations.SetBinding(TextList[TextList.Count - 1], WidthProperty, binding);
                                        TextOne.OverflowContentTarget = TextList[TextList.Count - 1];
                                    }
                                    else
                                    {
                                        ThereIsText = false;
                                        BindingOperations.SetBinding(TextList[TextList.Count - 1], WidthProperty, binding);
                                    }
                                }
                                else
                                {
                                    await Task.Delay(20);
                                    if (TextList[TextList.Count - 1].HasOverflowContent)
                                    {
                                        TextList.Add(new RichTextBlockOverflow() { Width = ViewModel.ColumnWidthInt, Margin = new Thickness(20) });
                                        BindingOperations.SetBinding(TextList[TextList.Count - 1], WidthProperty, binding);
                                        StackViewer.Children.Add(TextList[TextList.Count - 1]);
                                        TextList[TextList.Count - 2].OverflowContentTarget = TextList[TextList.Count - 1];
                                    }
                                    else
                                    {
                                        ThereIsText = false;
                                        BindingOperations.SetBinding(TextList[TextList.Count - 1], WidthProperty, binding);
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        RichTextBlockOverflow TextOne = StackViewer.Children[a] as RichTextBlockOverflow;
                        if (!TextOne.HasOverflowContent && a < ChildrenList[0])
                        {


                            for (int b = a + 1; b <= ChildrenList[0]; b++)
                            {
                                StackViewer.Children.RemoveAt(a + 1);
                                TextList.RemoveAt(a);
                            }

                            await Task.Delay(300);
                            if (TextList.Count > 0)
                            {
                                FindCorrectColumn("ChangeMeasures");
                                if (numCol > correctColumnNumber)
                                {
                                    ScrollToElement(PageViewer, TextList[numCol], 20, false, false, null);
                                }
                                else
                                {
                                    ScrollToElement(PageViewer, TextOneRich, 20, false, false, null);
                                }
                            }

                            BaseGrid.Opacity = 100;
                            return;
                        }
                        else if (TextOne.HasOverflowContent && a == ChildrenList[0])
                        {
                            bool ThereIsText = true;
                            await Task.Delay(300);
                            if (TextList.Count > 0)
                            {
                                FindCorrectColumn("ChangeMeasures");
                                if (numCol > correctColumnNumber)
                                {
                                    ScrollToElement(PageViewer, TextList[numCol], 20, false, false, null);
                                }
                                else
                                {
                                    ScrollToElement(PageViewer, TextOneRich, 20, false, false, null);
                                }
                            }
                            BaseGrid.Opacity = 100;

                            while (ThereIsText)
                            {
                                await Task.Delay(20);
                                if (TextList[TextList.Count - 1].HasOverflowContent)
                                {
                                    TextList.Add(new RichTextBlockOverflow() { Width = ViewModel.ColumnWidthInt, Margin = new Thickness(20) });
                                    BindingOperations.SetBinding(TextList[TextList.Count - 1], WidthProperty, binding);
                                    StackViewer.Children.Add(TextList[TextList.Count - 1]);
                                    TextList[TextList.Count - 2].OverflowContentTarget = TextList[TextList.Count - 1];
                                }
                                else
                                {
                                    ThereIsText = false;
                                    BindingOperations.SetBinding(TextList[TextList.Count - 1], WidthProperty, binding);
                                }
                            }
                        }
                    }
                }
            });
        });
        BaseGrid.Opacity = 100;
    }

    private async void btnLoadText_Click(object sender, RoutedEventArgs e)
    {

        await Task.Run(async () =>
        {
            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            {
                TextLoaded = true;
                Paragraph paragraphText = new Paragraph();
                paragraphText.Inlines.Add(new Run {Text = "" }); //** The text in the link must be pasted in the "Run" of this paragraph.
                LoadText(paragraphText);
            });
        });
    }

    private async void LoadText(Paragraph paragraph)
    {
        await Task.Run(async () =>
        {
            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
            {
                bool first = true;
                bool TereIsText = true;
                TextOneRich.Blocks.Add(paragraph);
                while (TereIsText)
                {
                    if (first)
                    {
                        await Task.Delay(20);
                        if (TextOneRich.HasOverflowContent)
                        {
                            TextList.Add(new RichTextBlockOverflow() { Width = ViewModel.ColumnWidthInt, Margin = new Thickness(20) });
                            BindingOperations.SetBinding(TextList[0], WidthProperty, binding);
                            StackViewer.Children.Add(TextList[0]);
                            TextOneRich.OverflowContentTarget = TextList[0];
                            first = false;
                        }
                        else
                        {
                            TereIsText = false;
                        }
                    }
                    else
                    {
                        await Task.Delay(20);
                        if (TextList[TextList.Count - 1].HasOverflowContent)
                        {
                            TextList.Add(new RichTextBlockOverflow() { Width = ViewModel.ColumnWidthInt, Margin = new Thickness(20) });
                            BindingOperations.SetBinding(TextList[TextList.Count - 2], WidthProperty, binding);
                            StackViewer.Children.Add(TextList[TextList.Count - 1]);
                            TextList[TextList.Count - 2].OverflowContentTarget = TextList[TextList.Count - 1];
                        }
                        else
                        {
                            TereIsText = false;
                            BindingOperations.SetBinding(TextList[TextList.Count - 1], WidthProperty, binding);
                        }
                    }
                }
            });
        });
    }

    double correctColumnNumber;
    double correctWidth;

    private void PageViewer_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        if (TextLoaded)
        {
            BaseGrid.Opacity = 0;
        }

        correctColumnNumber = Math.Truncate(PageViewer.ActualWidth / Convert.ToInt32(500)) + 1;
        correctWidth = (PageViewer.ActualWidth / correctColumnNumber) - 40;
        if (correctColumnNumber != 0)
        {
            ViewModel.ColumnWidthInt = correctWidth;
        }

        numCol = Convert.ToInt32(correctColumnNumber) - 1;
        timerSize.Stop();
        timerSize.Start();
    }

    private async void btnDecFont_Click(object sender, RoutedEventArgs e)
    {
        await Task.Run(async () =>
        {
            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            {
                TextOneRich.FontSize -= 1;
                timerSize.Stop();
                timerSize.Start();
            });
        });
    }

    private async void btnIncFont_Click(object sender, RoutedEventArgs e)
    {
        await Task.Run(async () =>
        {
            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            {
                TextOneRich.FontSize += 1;
                timerSize.Stop();
                timerSize.Start();
            });
        });
    }

    private void btnBack_Click(object sender, RoutedEventArgs e)
    {
        timerFoBA.Start();
        btnBack.IsEnabled = false;

        FindCorrectColumn("Back");
        if (numCol == 10000000)
        {

        }
        else if (numCol != -1)
        {
            ScrollToElement(PageViewer, TextList[numCol], 20, false, true, null);
        }
        else
        {
            ScrollToElement(PageViewer, TextOneRich, 20, false, true, null);
        }
    }

    private void btnForward_Click(object sender, RoutedEventArgs e)
    {
        if (PageViewer.ScrollableWidth != PageViewer.HorizontalOffset)
        {
            timerFoBA.Start();
            btnForward.IsEnabled = false;

            FindCorrectColumn("Forward");
            try
            {
                if (numCol == -1)
                {
                    numCol = 0;
                }
                ScrollToElement(PageViewer, TextList[numCol], 20, false, true, null);
            }
            catch { }
        }
    }


    private void timerFoBA_tick(object sender, object e)
    {
        timerFoBA.Stop();
        btnBack.IsEnabled = true;
        btnForward.IsEnabled = true;
    }

    private void ScrollToElement(ScrollViewer scrollViewer, UIElement element, double margin, bool isVerticalScrolling = true, bool smoothScrolling = true, float? zoomFactor = null)
    {
        var transform = element.TransformToVisual((UIElement)scrollViewer.Content);
        var position = transform.TransformPoint(new Point(0, 0));

        if (isVerticalScrolling)
        {
            scrollViewer.ChangeView(null, position.Y, zoomFactor, !smoothScrolling);
        }
        else
        {
            scrollViewer.ChangeView(position.X - margin, null, zoomFactor, !smoothScrolling);
        }
    }

    private void FindCorrectColumn(string ForwardBack)
    {
        bool columnFind = false;
        bool currentColumn = false;
        int exactColumn = 0;
        int cont = 0;
        while (!columnFind)
        {
            try
            {
                Rect elementBounds = TextList[cont].TransformToVisual(PageViewer).TransformBounds(new Rect(0.0, 0.0, TextList[cont].ActualWidth, TextList[cont].ActualHeight));
                Rect containerBounds = new Rect(0.0, 0.0, PageViewer.ActualWidth, PageViewer.ActualHeight);
                currentColumn = (elementBounds.Left < containerBounds.Right && elementBounds.Right > containerBounds.Left);
                if (currentColumn)
                {
                    exactColumn = cont;
                    columnFind = true;
                }
                else
                {
                    cont += 1;
                }
            }
            catch
            {
                numCol = -1;
                columnFind = true;
                return;
            }
        }

        if (ForwardBack == "Forward")
        {
            exactColumn += 1;
            numCol = Convert.ToInt32(((Math.Truncate((exactColumn / correctColumnNumber))) * correctColumnNumber) + (correctColumnNumber - 1));
        }
        else if (ForwardBack == "ChangeMeasures")
        {
            numCol = exactColumn;
        }
        else
        {
            numCol = Convert.ToInt32((Math.Truncate((exactColumn / correctColumnNumber)) * correctColumnNumber) - 1);
        }
    }
}

ColumnWidthClass.cs:

代码语言:javascript
复制
class ColumnWidthClass : INotifyPropertyChanged
{
    private double columnwidthint = 350;
    public double ColumnWidthInt
    {
        get
        {
            return columnwidthint;
        }
        set
        {
            columnwidthint = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ColumnWidthInt)));
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

我想加速的是"LoadText“方法但是..。我不能..!做这个的方法?

要粘贴在btnLoadText_Click中的"Run“段落中的文本位于以下链接:文本加载中。

EN

回答 1

Code Review用户

发布于 2017-12-07 23:31:53

这是很多我无法运行的代码所以我猜.

等待Task.Delay(20);

如果您想加快代码的速度,那么为什么会有延迟呢?他们没有被记录在案。这是否是一种黑客攻击,因为否则LoadText的工作速度太快?

尝试{ if (numCol == -1) { numCol = 0;} ScrollToElement(PageViewer,TextListnumCol,20,false,true,null);} catch {}

另一个猜测是您在这里使用try/catch块。我认为您可能在这里使用无效的索引。您应该使用一个简单的条件来检查它们是否超出了范围,而不是捕获它们。

(!columnFind) { try { Rect elementBounds = TextList续 .TransformToVisual(PageViewer) .TransformBounds(新Rect(0.0,0.0,TextList续.ActualWidth,TextList续.ActualHeight));Rect containerBounds =新Rect(0.0,0.0,PageViewer.ActualWidth,PageViewer.ActualHeight);currentColumn = (elementBounds.Left <&try;en19#>);如果(currentColumn) { exactColumn = cont;columnFind = true;} columnFind { cont += 1;} catch { numCol = -1;columnFind= true;返回;}

这里我们也有类似的情况。您应该消除它们,并确保索引是有效的,而不是误用异常捕获。首先要尽量避免例外。如果太频繁的话,捕捉它们会降低性能。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/181959

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档