Решение WPF для отображения сообщений чата приложения IRC

Я создаю свое первое приложение WPF, которое представляет собой программу чата IRC. Поскольку я новичок в WPF, я действительно не знаю, как мне отображать сообщения, потому что они могут содержать жирные, курсивные слова или даже изображения, или сообщение о выходе имеет другой цвет, чем простое сообщение.

Я искал в сети, и я нашел несколько решений. Первый тип решений — использовать RichTextBox с FlowDocument или просто простой FlowDocument и каким-то образом взломать их систему привязки, чтобы отобразить значение свойства. Что касается «взлома», я имею в виду, что эти элементы управления не имеют свойств привязки, потому что они не являются DependencyObjects. (Я не уверен, что это правильное выражение).

В простом TextBlock я не могу отображать сообщения, потому что он отображает значение строки. После большого количества сообщений в простой строке и добавления к ней нового требуется много копий памяти, поскольку строка не может быть изменена. И, кроме того, если я использую TextBlock, могу ли я выбрать его содержимое с помощью мыши, чтобы скопировать из него? Если я использую текстовое поле только для чтения, могу ли я использовать стиль, например, только для одного слова?

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

Было бы здорово использовать список для хранения сообщений, потому что после ~ 1000 сообщений я хотел бы удалить первые 100, чтобы сохранить их в файле журнала.

Поэтому я полностью запутался в том, как решить эту проблему. Я надеюсь, что у кого-то будет правильное решение для такого рода проблемы!


person user2042930    schedule 25.12.2013    source источник
comment
См. www.squiggle.codeplex.com   -  person Reza ArabQaeni    schedule 25.12.2013


Ответы (1)


Ну, как вы знаете, есть много возможностей.

Одна из возможностей состоит в том, чтобы иметь ObservableCollection<string>, где каждый элемент представляет собой HTML. Вы можете использовать ListBox/ItemsControl для привязки этих строк. В ItemsControl DataTemplate вы можете добавить элемент TextBlock и привязать его свойство Text к строке.

Хитрость заключается в использовании Converter, который может изменять коллекцию Inlines TextBlock и генерировать конкретные элементы Run() для TextBlock из строки HTML. Обратите внимание, что TextBlock может подчеркивать/каждое слово разным цветом и многое другое. В Интернете полно таких проектов (Google TextBlock отображает HTML).

Будет сложнее реализовать Image. Насколько я знаю, вы не можете поместить его в TextBlock. Это зависит от ваших требований, как разрешено вставлять изображение. Возможно, вам придется разделить ОДНУ строку на «несколько» TextBlocks, между которыми находится элемент Image().

А еще есть RichTextDocument, однако он звучит не слишком хорошо для IRC-клиента. Вам не нужна большая часть этой функциональности, она усложнит работу и будет работать медленнее.

person Erti-Chris Eelmaa    schedule 25.12.2013
comment
Да, я тоже думал об этом решении, но у TextBlocks есть один большой недостаток: их содержимое нельзя выбрать, и я думаю, что это основное требование такого приложения. - person user2042930; 25.12.2013
comment
Это аргумент. Взгляните на это решение: stackoverflow.com/questions/136435/ Не совсем уверен, как это согласуется с текущей проблемой, но где-то глубоко в моей голове все должно работать: p - person Erti-Chris Eelmaa; 25.12.2013
comment
К сожалению нет. Когда я хочу выбрать сообщение из TextBlock, они предлагают использовать TextBox только для чтения, когда я хочу иметь стиль в TextBox, они предлагают использовать TextBlock. :/ - person user2042930; 25.12.2013
comment
Истинный. Теперь, когда я немного больше думаю о функциональности выбора; что в нем такого особенного? Захватите начальные и конечные координаты и рассчитайте набор элементов Run(), для которых необходимо временно изменить фон. WPF имеет потрясающую систему проверки на попадание, и она может сообщить вам все возможные элементы Run(), которые находятся на прямоугольнике xy. Звучит неплохо. Данный Squiggle, похоже, использует FlowDocument для своей функциональности => squiggle. codeplex.com/SourceControl/latest#Squiggle.UI/Controls/ - person Erti-Chris Eelmaa; 25.12.2013
comment
Я, возможно, съел слишком много львиной еды утром - вычисление правильной области выбора и временное разделение элементов Run на правильных границах ни в коем случае не является легкой задачей, и ее следует пытаться использовать только в исследовательских целях, или если RTF оказался слишком неуклюжим и медленный. Вам лучше использовать FlowDocument, как это делает SQuiggle. - person Erti-Chris Eelmaa; 25.12.2013