I'm trying to learn WPF and was thinking about creating a simple IRC client. The most complicated part is to create the chat log. I want it to look more or less like the one in mIRC:
or irssi:
The important parts are that the text should be selectable, lines should wrap and it should be able to handle quite large logs.
The alternatives that I can come up with are:
StackPanel inside a ScrollViewer where each line is a row
ListView, since that seems more suitable for dynamic content/data binding.
Create an own control that does the rendering on its own.
Is there any WPF guru out there that has some ideas on which direction to take and where to start?
I suggest you start with a good object model independent of the UI, and then try a multi-line TextBox or a RichTextBox.
Whether these will suffice will depend on exactly how long you want the log to be able to get. If you run into performance issues, you may need to look at virtualization.
First of all, you should consider if you want to select only entire row (like in a listbox), or if you want to select certain characters from a row (like in a textbox).
In the first case, I think a ListView or even a ListBox should be enough, both of them support virtualization when bound to collection and there should be no problem with huge amounts of data. A stack panel inside a ScrollViewer is a little bit like reinventing the wheel for this case and creating a new control is not a very inspired approach in my opinion (as the functionality you want can be achieved with the existing controls, in WPF).
In the second case, if you want to select some text inside of a line, or if you want word wrapping for your longest lines in the log and want to select individual parts of the wrapped lines, then you need to use a control more oriented on displaying text. Kent already suggested a RichTextBox, I would add AvalonEdit control or even the WebBrowser control in which you directly modify its HTMLDocument.
I would suggest to use RichTextBox too, and store items in a log file or database, if you run into performance issues.
Another solution is to use the WPF WebBrowser control and modifiy its HTML content with:
webBrowser.NavigateToString("<HTML><H2><B>This page comes using String</B><P></P></H2></HTML>");
More information about using WebBrowser control
Related
My program will prompt the user for a number, i.e. 25. The program will then start the "main form" with 25 controls (textbox). The 25 (or whatever number) of textboxes (or whatever control) will need to be formatted evenly. I will also need to be able to retrieve the text (or another property if I use another control) in order, from left to right and up to down. What is the best method of approaching this?
Using WPF MVVM. In a .XAML file, create a DataTemplate with the DataType of a ViewModel that will provide the binding for your TextBoxs, lets call this the TextboxViewModel. Then using a ItemsControl element with an ItemsSource of TextboxViewModel. You'll be able to instantiate as many TextBoxs as you want and be able to get the result by browsing through your list of TextboxViewModel.
Supposing you are using Windows Forms here.
Dynamically create the X controls and add them to the Controls collection of your form. To ease the access to them you can store their reference in a List and set some event handlers too, depending on your needs. You just need to calculate their positions while you add them.
If WinForms, this is exactly what the FlowLayoutPanel is for. Just add the controls to it and they will arrange themselves automatically, wrapping down to the next row as needed. As Mihai already suggested, you could also keep reference to those controls in a List.
Another option would be to use a TableLayoutPanel. It's a little more difficult to learn and use, but is much more flexible and powerful.
I am currently developing a chat application in C# and I would like to know which form control allows to add text retaining control to each specific message to modify it later on when is required. I want this in order to be able to add a double tick when the message is received in the other side of the communication, pretty much like in "Whatsapp".
I've thought about an approach consisting on each message object firing events (like "sent", "received"..) when it changes that are listened by the corresponding form control that serves as the view, adding the above mentioned tick.
Any advice on how to achieve this goal? I've tried TextBox but Lines property force to have control os indexes and I want it to be completely event driven. Currently I stuck with DataGridView, however I've made little to no progress.
Thanks!
No one ready made Control I can think of will do the job, I'm afraid.
I would use a FlowLayoutPanel and add a Label for each chunk of text that gets added to the chat.
You can use MeasureString with a given width to get the height of the Label. (AutoSize should be off.)
The Labels would get the Width of the FLP and you could keep a List<> of the Labels with maybe a few meta data, like user, time etc..
Sounds like a good candidate for a ChatDisplay class to bundle the whole functionality!
Of course as the Labels are Controls you can add events to them as you like to communicate with the ChatDisplay or even with an outside communications object.. And the ChatDisplay class is free to implement whatever you need anyway. If necessary you can wrap the Labels in a ChatItem class, too.
Much more extensible than digging into a DGV to force it into doing things it was not meant to do..
I need control in winforms that can add tens lines per second. I use now richtextbox, but i'm looking for something with sorting possibility (according some datatime or int)
Lines which are added are just custom objects complex of several int and datetime.
Delay aspect is quite important here.
EDIT:
It can be also some table/grid, but I suppose it take too much time (searching existing lines and inserting new line into appropriate place)
RichTextBox will typically offer more overhead in managing, searching, and inserting.
Much more appropriate would be a control like ListView. It gives simpler control over sorting, scrolling, and more.
Additionally, ListView has the ability to handle Virtual data backing. If performance or content size is an issue, this will let you only worry about the sub-set currently displayed in the ListView "view" window.
Two options
Use RichTextBox as you are doing now hold the data in a structure like SortedList from which the control will be updated.
Or, you can use a Grid, format the look and feel of the grid to remove the row & column grid lines and each new line will get appended this way you can let user sort by clicking on the header...
As for adding say ten lines per second I am pretty certain both these controls can handle more traffic than that....
I have some strings that contain line breaks, and I would like to keep this formatting in each ListBox item that the strings are applied to.
Is there any way to do this?
Thanks
The ListBox in winforms doesn't support multiline/text wrapping. If you want that kind of behaviour you probably need to do a custom control or there may be a third party control.
There's a sample implementation at http://www.codeproject.com/articles/2695/an-editable-multi-line-listbox-for-net. It's old so there may be better implementations out there/at least you can see what's involved.
I found this code here which explains how to create custom controls. I have been using these controls as buttons, but now that I am beginning to understand the code a bit more, I would like to try and create a text box control using the same drawing techniques. I have been searching endlessly for some examples on the subject, but cannot find a single one. I don't understand how a textbox can be writable if a rectangle is being used to make it. Does anybody have any experience creating custom controls in C#? I would like for my textbox to be able to match the theme in the above link which is why it has to be custom made.
Well, at the beginning you should have in mind, that the implementation of new text box control is kinda complicate thing. It is necessary that you consider the following points:
1) What should your textbox do? How can the user interact with it? Which events do you necessarely throw?
2) How should you textbox be drawn? Is it a simple box with an outline or do you have elements which are different if the user gets interacted.
A good starting point for implementing your own textbox is to look how it works under the hood - in fact, you should start by referencing to samples which came from the DirectX and DirectDrawing area, one example is the following link (the sample is for c++, but the concepts are the same as used in windowsforms or wpf drawing):
http://www.uc-forum.com/forum/d3d-tutorials-and-source/65377-make-textbox-ingame-console-directx.html
a more direct sample (explaining howto extend an existing textbox) can be found here:
http://www.codedblog.com/2007/09/17/owner-drawing-a-windowsforms-textbox/
All in all, to achieve your goal try to extend the basic text box at the beginning and afterwards start with a component which is not that complicated, for example a simple checkbox. Go on and at the end you will be able to implement your own textbox control ;)