Перенос слов WPF: пропущенные слова при использовании пользовательского шрифта

Я использую собственный шрифт, известный как Pigiarniq, в приложении WPF. Я обнаружил, что время от времени слова исчезают из текстовых блоков, использующих этот шрифт. Исчезающие слова должны были появиться в конце строки, в которой они находятся, или, возможно, в следующей строке, что заставляет меня думать, что что-то не так с переносом текста. Я, наконец, (после больших трудностей) изолировал проблему в небольшом фрагменте кода (ПРИМЕЧАНИЕ: это всего лишь тест для подтверждения возникновения проблемы. Это не часть моей программы):

<Window x:Class="Test_the_textbox_width.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="850">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition />
    </Grid.RowDefinitions>
    <Grid 
          HorizontalAlignment="Center">
    <TextBlock HorizontalAlignment="Left"
               Name="textBlock1"
               VerticalAlignment="Top"
               FontFamily="Pigiarniq%20Regular.ttf#Pigiarniq"
               TextWrapping="Wrap"
               FontSize="15"
               Margin="10">
        <TextBlock.Text>
             You do not need to enter both manually. Rates are calculated using true depositional 
            (uncompacted) thicknesses, rather than measured present-day thicknesses.
        </TextBlock.Text>
    </TextBlock>
    </Grid>

</Grid>

The word "thicknesses" that occurs after "(uncompacted)" does not appear. If I resize the window manually using the window handle, it will re-appear.

ПРИМЕЧАНИЕ. Я поместил TextBlock в элемент Grid выше, потому что иногда эта проблема возникает, когда TextBlock находится в Grid. В другом случае он находился внутри InlineUIContainer. Были и другие случаи.

Я обнаружил, что такое поведение не возникает, если я явно устанавливаю ширину, например, если я подписываюсь на событие Loaded в TextBlock:

private void textBlock1_Loaded(object sender, RoutedEventArgs e)
    {
        textBlock1.Width = textBlock1.ActualWidth;
        //textBlock1.Width = Double.NaN;  //if you leave this in, you get the bad behaviour
    }

Очень странно! Любые идеи о том, как предотвратить это? Мой босс очень хотел бы использовать этот шрифт, поэтому я не могу просто выбрать другой шрифт (я никогда не видел, чтобы это происходило с любым другим шрифтом). Я также не слишком заинтересован в идее наблюдения за каждым изменением в макете и соответствующим изменением размера каждого текстового блока, который использует Pigiarniq.


person skybluecodeflier    schedule 29.03.2011    source источник
comment
почему вы хотите textBlock1.Width = Double.NaN; в TextBox.Loaded обработчике событий?   -  person publicgk    schedule 30.03.2011
comment
Я сомневаюсь, что это как-то связано с самим шрифтом. Попробуйте любой другой шрифт, поэкспериментируйте с Width="850", и я уверен, вы найдете значения, которые скрывают текст и от других шрифтов. Ваша композиция немного неясна. Почему вы помещаете текстовый блок в другую сетку? Я думаю, что этот текстовый блок в сетке в сетке немного все портит. Кроме того, оставьте это событие Loaded вне. Не понимаю, почему это должно быть там.   -  person Markus Hütter    schedule 30.03.2011
comment
@publicgk: я не знаю. Я доказывал, что если вы переключите ширину TextBlock обратно на Auto (что эквивалентно установке его на NaN), плохое поведение вернется.   -  person skybluecodeflier    schedule 30.03.2011
comment
@Markus: я пытался немного воспроизвести это поведение с несколькими другими шрифтами (с текстом в текстовом блоке выше) - у меня не было успеха. Если кто-нибудь найдет пример того, как это происходит в другом шрифте, дайте мне знать. Кажется, это очень зависит от контекста. О композиции: я пытался воспроизвести поведение, которое имело место в моей программе, поэтому мне не пришлось бы размещать большую базу кода на SO. Текстовые блоки, у которых есть эта проблема, иногда встречаются в сетках. О загруженном событии: мне не нужно загруженное событие. Но без него возникает проблема.   -  person skybluecodeflier    schedule 30.03.2011
comment
@skybluecodeflier попробуйте проверить текстовый блок с помощью Snoop и посмотреть, получил ли он допустимые значения для DesiredSize и ActualSize (также проверьте, правильно ли отображается текстовое поле в Snoop). Я действительно думаю, что это больше проблема в том, что сетка обрезает текстовый блок и не имеет ничего общего с текстовым блоком.   -  person Markus Hütter    schedule 30.03.2011
comment
@skybluecodeflier, сталкиваетесь ли вы с той же проблемой, если вы устанавливаете ширину TextBlock на Auto через XAML (т.е. ‹TextBlock Width=Auto ... /›) и не через обработчик события Loaded. Я считаю, что основная причина проблемы заключается в том, что вы пытаетесь установить ширину элемента управления после того, как система вычислила фактическую ширину, но до того, как она отобразит текстовый блок. Из MSDN событие Loaded возникает перед финальным рендеринга, но после того, как система макета вычислит все необходимые значения для рендеринга.   -  person publicgk    schedule 30.03.2011
comment
@Markus: я посмотрел со Снупом. Желаемая ширина оказывается больше фактической ширины примерно на 20 провалов (независимо от устройства в пикселях), но это кажется более или менее постоянным независимо от того, возникает проблема или нет. Однако я не уверен, что это значит - почему TextBlock не всегда получает желаемую ширину? Кроме того, я не уверен, что вы имели в виду, говоря, что TextBlock правильно отображается в Snoop - свойства выглядят нормально, и они выглядят точно так же в окне Magnify. Я также попытался удалить ОБЕ сетки, внутри которых находился TextBlock, - не помогло.   -  person skybluecodeflier    schedule 31.03.2011
comment
@publicgk: Да, проблема остается. На самом деле я добавил обработчик события Loaded ПОСЛЕ того, как обнаружил проблему. В основном я пытался понять, решит ли проблему установка ширины текстового блока на значение. Обработчик Loaded доказал, что он решит проблему. Поэтому я решил посмотреть, не вызовет ли проблема снова исправление ширины, а затем изменение ее обратно на Auto. Если бы это не вызвало проблемы, то первоначальный рендеринг был бы подозрительным. Но это все еще вызывает проблему, поэтому я не знаю, что не так. Это имело смысл?   -  person skybluecodeflier    schedule 31.03.2011


Ответы (2)


На самом деле мы столкнулись с той же проблемой с системным шрифтом по умолчанию. Похоже, это ошибка самой функции разрыва строки текстового блока.

Мы обнаружили, что в окнах фиксированного размера разрыв строки иногда игнорирует последнее слово. Это происходило для различных размеров и предложений.

Мы не смогли найти реального решения, поэтому наш обходной путь заключался в том, чтобы вручную включать разрывы строк в текст.

Мы также немного погуглили по этому вопросу, потому что я отказывался верить, что такая проблема не задокументирована... но, похоже, это недокументировано (или, по крайней мере, трудно найти два месяца назад), и после очень тщательного тестирования я я убежден, что это на самом деле ошибка.

person NightDweller    schedule 03.04.2011
comment
Из любопытства, вы уже опубликовали это как ошибку на странице connect.microsoft.com? Если нет, я опубликую эту ошибку там. - person skybluecodeflier; 05.04.2011
comment
На самом деле я использовал тот же обходной путь для некоторых проблем, с которыми столкнулся. Однако это сложно сделать, когда у вас много текста. - person skybluecodeflier; 05.04.2011
comment
:) нет - слишком ленив, чтобы написать отчет об ошибке, я должен сказать, что это своего рода тривиальная ошибка (в том смысле, что я ожидал, что она будет широко распространена и хорошо известна), и я немного удивлен, что это не было сообщалось или даже упоминалось где-либо... - person NightDweller; 07.04.2011
comment
В порядке. Так что я только что нашел время, чтобы опубликовать сообщение об ошибке на сайте Microsoft. Вот ссылка. Я был бы признателен, если бы вы зашли туда и указали, что можете воспроизвести эту ошибку. Надеюсь, файл моего проекта скоро появится у них... - person skybluecodeflier; 12.04.2011
comment
Кроме того, я пока не собираюсь отмечать это как ответ. То есть, пока я не получу какой-то удовлетворительный ответ от Microsoft. Я надеюсь на лучшее решение, чем то, что мы выяснили до сих пор. Спасибо за вашу помощь! - person skybluecodeflier; 12.04.2011

Я смог обойти это, установив TextAlignment="Left" и HorizontalAlignment="Stretch" в TextBlock.

person Ben Schoepke    schedule 16.10.2013