缺少Xaml TextBlock中的中间单词,但最后一个单词不是

时间:2017-10-25 17:41:55

标签: c# wpf xaml

我有一些文字我试图在xaml中显示,但看起来它在中间被切断了,但是下一个单词出现了。这是我的xaml。

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="115" />
    </Grid.ColumnDefinitions>
    <TextBlock TextWrapping="Wrap" HorizontalAlignment="Center" FontFamily="Arial" FontSize="13.33333333">ABCDE IAATA Corp.</TextBlock>
</Grid>                         

Which results in this。请注意,缺少中间字(IAATA),但最后一个字(Corp。)就在那里。知道这里发生了什么吗?我希望第三个单词会被包裹到一个新行上,或者第二个单词出现,最后一个单词被截断,或者甚至第二个和第三个单词都被截断但不是这样。

我能够在VS和Kaxaml中测试这个

更新 对于更多上下文,进入的xaml是从else where生成的。我后来对xaml元素进行了一些测量,这会导致一个&lt; fatalExecutionEngineError&#39;异常,立即杀死应用程序。

消息是

Managed Debugging Assistant 'FatalExecutionEngineError' has detected a problem in 
'C:\Projects\TestFailFast\TestFailFast\bin\Debug\TestFailFast.vshost.exe'.

Additional information: The runtime has encountered a fatal error. The address of the error was at 0x583ee28b, on thread 0x2af0. The error code is 0x80131623. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack

并且通过事件查看器日志获得的堆栈跟踪是

Application: Services.BackEnd.exe Framework Version: v4.0.30319 

Description: The application requested process termination through System.Environment.FailFast(string message). 
Message: Unrecoverable system error. 
Stack: at 
  System.Environment.FailFast(System.String) at 
  System.Windows.Controls.TextBlock.IsAtCaretUnitBoundary(System.Windows.Documents.ITextPointer, Int32, Int32) at 
  System.Windows.Documents.TextContainer.IsAtCaretUnitBoundary(System.Windows.Documents.TextPointer) at 
  System.Windows.Documents.TextPointer.System.Windows.Documents.ITextPointer.get_IsAtCaretUnitBoundary() at System.Windows.Documents.TextPointerBase.IsAtCaretUnitBoundary(System.Windows.Documents.ITextPointer) at System.Windows.Documents.TextPointerBase.MoveToNextInsertionPosition(System.Windows.Documents.ITextPointer, System.Windows.Documents.LogicalDirection) at 
  System.Windows.Documents.TextPointer.System.Windows.Documents.ITextPointer.GetNextInsertionPosition(System.Windows.Documents.LogicalDirection) 
...

仅当我将上述xaml包装在像

这样的FixedDocument中时才会暴露
<FixedDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<PageContent>
    <FixedPage>
        <Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="115" />
            </Grid.ColumnDefinitions>
            <TextBlock Text="ABCDE IAATA Corp." FontFamily="Arial" FontSize="13.333333" TextWrapping="Wrap" HorizontalAlignment="Center"/>
        </Grid>
    </FixedPage>
</PageContent>
</FixedDocument>

我这里有一个样本重现器

class Program {
    [STAThread]
    static void Main(string[] args) {
        var fixedPageXaml = @"<FixedDocument xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"">
<PageContent>
    <FixedPage>
        <Grid xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width=""115"" />
            </Grid.ColumnDefinitions>
            <TextBlock Text=""ABCDE IAATA Corp."" FontFamily=""Arial"" FontSize=""13.333333"" TextWrapping=""Wrap"" HorizontalAlignment=""Center""/>
        </Grid>
    </FixedPage>
</PageContent>
</FixedDocument>";

        //Search through all xaml elements untill the TextBlock is found
        var textBlock = FindTextBlock(XamlReader.Parse(fixedPageXaml));
        var inline = textBlock.Inlines.FirstInline;

        //Get a TextPointer to the end of a line that is specified relative to the current text pointer 
        // Add 1 to get the beginning of the line following the one count is requesting
        var nextLineStart = inline.ElementStart.GetLineStartPosition(0 + 1); 

        if (nextLineStart != null) {
            //Get the insertion position at the end of the document
            //CRASH!
            var nextPos =  nextLineStart.GetNextInsertionPosition(LogicalDirection.Backward);
        }


        Console.WriteLine("Done");
        Console.Read();
    }

    private static TextBlock FindTextBlock(object root) {
        var fe = root;
        while (fe.GetType() != typeof(TextBlock)) {
            if (fe is FixedDocument) {
                foreach (var p in ((FixedDocument)fe).Pages) {
                    var ret = FindTextBlock(p);
                    if (ret != null) {
                        return ret;
                    }
                }
            } else if (fe is FixedPage) {
                foreach (UIElement c in ((FixedPage)fe).Children) {
                    var ret = FindTextBlock(c);
                    if (ret != null) {
                        return ret;
                    }
                }
            } else if (fe is PageContent) {
                fe = ((PageContent)fe).Child;
            } else if (fe is Grid) {
                foreach (UIElement c in ((Grid)fe).Children) {
                    var ret = FindTextBlock(c);
                    if (ret != null) {
                        return ret;
                    }
                }
            }
        }
        if (fe.GetType() == typeof(TextBlock)) {
            return fe as TextBlock;
        } else {
            return null;
        }
    }
}

这是在.net版本4.6.2

中测试的

1 个答案:

答案 0 :(得分:3)

如果希望文本块的宽度与父级相同,请不要将Horizo​​ntalAlignment设置为Left。作为网格子,它默认为Stretch,这是你想要的。如果需要,在TextBlock上设置TextAlignment以对齐文本。

我想知道这对于包装算法中的算术可能不是一个有趣的角落,其中“缺失”文本只是放在视线之外:如果我将FontSize调到13.256(但不是13.257),它会换行正常。如果我将它拨到13.341(但不是13.3405),它会正确包装。