У меня проблемы с тем, чтобы Silverlight 2.0 выложил текст именно так, как я хочу. Мне нужен текст с разрывами строк и встроенными ссылками, с переносом, как текст HTML на веб-странице.
Вот самое близкое, что я пришел:
<UserControl x:Class="FlowPanelTest.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls"
Width="250" Height="300">
<Border BorderBrush="Black" BorderThickness="2" >
<Controls:WrapPanel>
<TextBlock x:Name="tb1" TextWrapping="Wrap">Short text. </TextBlock>
<TextBlock x:Name="tb2" TextWrapping="Wrap">A bit of text. </TextBlock>
<TextBlock x:Name="tb3" TextWrapping="Wrap">About half of a line of text.</TextBlock>
<TextBlock x:Name="tb4" TextWrapping="Wrap">More than half a line of longer text.</TextBlock>
<TextBlock x:Name="tb5" TextWrapping="Wrap">More than one line of text, so it will wrap onto the following line.</TextBlock>
</Controls:WrapPanel>
</Border>
</UserControl>
Но проблема в том, что хотя текстовые блоки tb1 и tb2 будут идти в одну и ту же строку, потому что для них достаточно места, tb3 и далее не будут начинаться на той же строке, что и предыдущий блок, даже если он будет перенесен на следующие строки.
Я хочу, чтобы каждый текстовый блок начинался там, где заканчивается предыдущий, на той же строке. Я хочу поместить обработчики событий клика в некоторый текст. Я также хочу разрывы абзаца. По сути, я пытаюсь обойти отсутствие элементов управления FlowDocument и Hyperlink в подмножестве Silverlight 2.0 XAML.
Чтобы ответить на вопросы, поставленные в ответах:
Почему бы не использовать прогоны для текста, не реагирующего на нажатия? Если я просто использую отдельные текстовые блоки только для текста, на который можно нажимать, то эти фрагменты текста будут по-прежнему страдать от проблемы переноса, показанной выше. И TextBlock непосредственно перед ссылкой, и TextBlock сразу после. По сути все это. Не похоже, что у меня много возможностей поместить несколько прогонов в один и тот же TextBlock.
Разделение ссылок от другого текста с помощью RegEx и циклов не является проблемой вообще, проблема заключается в отображении макета.
Почему бы не поместить каждое слово в отдельный текстовый блок в WrapPanel Помимо того, что это некрасивый хак, это не очень хорошо работает с переносами строк - верстка неправильная.
Это также сделало бы стиль подчеркивания связанного текста прерывистой линией.
Вот пример с каждым словом в его собственном TextBlock. Попробуйте запустить его, обратите внимание, что перевод строки не отображается в нужном месте.
<UserControl x:Class="SilverlightApplication2.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls"
Width="300" Height="300">
<Controls:WrapPanel>
<TextBlock TextWrapping="Wrap">Short1 </TextBlock>
<TextBlock TextWrapping="Wrap">Longer1 </TextBlock>
<TextBlock TextWrapping="Wrap">Longerest1 </TextBlock>
<TextBlock TextWrapping="Wrap">
<Run>Break</Run>
<LineBreak></LineBreak>
</TextBlock>
<TextBlock TextWrapping="Wrap">Short2</TextBlock>
<TextBlock TextWrapping="Wrap">Longer2</TextBlock>
<TextBlock TextWrapping="Wrap">Longerest2</TextBlock>
<TextBlock TextWrapping="Wrap">Short3</TextBlock>
<TextBlock TextWrapping="Wrap">Longer3</TextBlock>
<TextBlock TextWrapping="Wrap">Longerest3</TextBlock>
</Controls:WrapPanel>
</UserControl>
А как насчет LinkLabelControl как здесь и здесь . У него те же проблемы, что и у подхода, описанного выше, так как он почти такой же. Попробуйте запустить образец и сделайте текст ссылки длиннее и длиннее, пока он не будет перенесен. Обратите внимание, что ссылка начинается с новой строки, чего не должно быть. Сделайте текст ссылки еще длиннее, чтобы текст ссылки был длиннее строки. Обратите внимание, что он не оборачивается, а обрезается. Этот элемент управления не обрабатывает разрывы строк и разрывы абзацев.
Почему бы не поместить весь текст в прогоны, обнаружить щелчки на содержащем текстовом блоке и выяснить, какой прогон был нажат
Запуски не имеют событий мыши, но содержащий TextBlock. Я не могу найти способ проверить, находится ли прогон под мышкой (IsMouseOver отсутствует в Silverlight) или найти ограничивающую геометрию прогона (без свойства clip).
Существует VisualTreeHelper.FindElementsInHostCoordinates ()
Код ниже использует VisualTreeHelper.FindElementsInHostCoordinates, чтобы получить элементы управления под щелчком. Выходные данные перечисляют TextBlock, но не Run, так как Run не является UiElement.
private void theText_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
// get the elements under the click
UIElement uiElementSender = sender as UIElement;
Point clickPos = e.GetPosition(uiElementSender);
var UiElementsUnderClick = VisualTreeHelper.FindElementsInHostCoordinates(clickPos, uiElementSender);
// show the controls
string outputText = "";
foreach (var uiElement in UiElementsUnderClick)
{
outputText += uiElement.GetType().ToString() + "\n";
}
this.outText.Text = outputText;
}
Использовать пустой текстовый блок с полем для пробела следующего содержимого на следующей строке
Я все еще думаю об этом.
Как рассчитать правильную ширину блока разрыва строки, чтобы принудительно вставить следующий контент в следующую строку? Слишком короткий, и следующий контент будет по-прежнему в той же строке справа. Слишком долго, и «перенос строки» будет в следующей строке с контентом после него. Вам придется изменить размер разрывов при изменении размера элемента управления.
Часть кода для этого:
TextBlock lineBreak = new TextBlock();
lineBreak.TextWrapping = TextWrapping.Wrap;
lineBreak.Text = " ";
// need adaptive width
lineBreak.Margin = new Thickness(0, 0, 200, 0);