I'm writing an analyzer,which shows the packets of a specific program.Some packets are very large and the listview shows only the first 15-20 characters :\
This is my code
string __str = String.Join(" ", data.Select(x => x.ToString("x2")).ToArray()); //covert the byte[](packet) to hex string
string __ascii = AsciiToString(data); //convert the byte[](packet) to ASCII
if (encrypted) FormMain.PFA(form => form.listViewAnalyzer.Items.Add("S<-C [ENCRYPTED] Blowfishkey = 0xFF"));
else FormMain.PFA(form => form.listViewAnalyzer.Items.Add("S<-C"));
ListViewItem item = new ListViewItem(__str); //create new item and place the packet as hex string
item.SubItems.Add(__ascii); //add the ascii variant as substring
FormMain.PFA(form => form.listViewAnalyzer.Items.Add(item)); //add the item
It must be a property that prohibits adding text with more than x lines,but I can't see it.
The listview will contain all the text, you just can't see it if it's too long or has multiple lines.
The way that Outlook and things like packet sniffers often work is that the listview is accompanied by a textbox or "preview" window. You could change your UI so that selecting the item in the listview displays the full details of the item in an outlook-style preview pane. Then you could have a large multiline textbox and anything else you wanted. I often do this by putting an object in the ListViewItem.Tag property, so that I can retrieve it in the UI and display in the preview when the ListView.SelectedIndexChanged event fires.
Alternatively, the preview could be on a dialog that pops up when you double-click. In fact, make the preview UI a UserControl, then you can do both!
listview shows only the first 15-20 characters :\
Maybe you need to make the column wider?
It must be a property that prohibits adding text with more than x lines,but I can't see it.
List view items don't wrap text, so technically they prohibit text with more than 1 line
Related
Ok, I'm trying to do something a little specific here. I want to get the location of the selected text in a textbox.
To elaborate- I can use location to select text. If I have a textBox1 I could do:
textBox1.SelectionStart = 1;
textBox1.SelectionLength = 4;
That would start at the second letter and select 4 letters.
What I want to do is the opposite: when the user selects text, I want to find out what the start is and what the length is (or what the start is and what the end is. Either will work).
I thought about just searching the string for the selectedtext (textBox1.SelectedText). The problem comes if it is a common word or a string that is used multiple times. For instance.
This is a cat. This is a cat. This is a cat.
If they select the second sentence, using SelectedText to search the string for that specific sentence does me no good. It could be either of the 3.
So, my question is: When the user clicks a button, how do I determine the exact elements that are selected by the user, so that I can later manipulate those specific elements? Important to note the later part- I likely will not only want to manipulate the text when the button is pressed. I will also want to manipulate it later, at a time when the text may no longer be highlighted. This means I'll want to store SOMETHING to tell me what specific parts of the sentence I'm dealing with. If that solution isn't viable, is there a solution you can think of where, in the above "this is a cat" example, the user could select the second sentence, hit a button, and then later I know which sentence was selected when he hit that button?
According to the documentation, SelectionStart and SelectionLength can be both set and read. Just use those.
You dont even need to know the position of selected text to manipulate them, to edit the text that you have selected in the text you can simple set the SelectedText property to the new edited value.
// if textBox1.text = "Hello World World"; with first "World" selected
textBox1.SelectedText = textBox1.SelectedText.Replace("World", "Raj");
// then it becomes "Hello Raj World"
Using C# and WinForms, I can set a form to be localizable, put a label on it, and set text for the label in as many languages as I want. The text will be stored as string resources in one resource file for each language. Then, a user can select a language and all labels on the form will change to the correct language.
This does not seem to work for combo boxes. I can add items to a combo box for a localizable form and they will be stored in resource files using names such as ComboBox1.Item, ComboBox1.Item1, and ComboBox1.Item2, but the displayed text does not change when the combo box changes.
I've seen various suggestions for how to localize combo boxes, based on binding them to dictionaries or lists of tuples, but it seems to me that if items are stored in resource strings, there should be some more automatic way to use those resource strings. Is there?
Edit: Here is what should be a minimal example. A form has a text box, a button, a label and a combo box. The label and combo box each have resources for French (fr-FR) and Spanish (es-ES). The language name is entered in the text box, and the button changes the form's language using the following method:
private void ChangeLanguage(string lang)
{
ComponentResourceManager crm = new ComponentResourceManager(typeof(Form2));
CultureInfo culture = CultureInfo.CreateSpecificCulture(lang);
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
foreach (Control c in this.Controls)
{
crm.ApplyResources(c, c.Name, culture);
}
}
The result is that the label's text changes but the text of the combo box items does not.
If you close and reopen the form, everything will work fine. But if you would like to change the culture without closing the form, you need to add extra processing for ComboBox:
if (c is ComboBox)
{
var combo = (ComboBox)c;
var count = combo.Items.Count;
combo.Items.Clear();
combo.BeginUpdate();
for (int i = 0; i < count; i++)
{
var number = i == 0 ? "" : $"{i}";
var item = crm.GetString($"{c.Name}.Items{number}");
combo.Items.Add(item);
}
combo.EndUpdate();
}
crm.ApplyResources(c, c.Name);
Also keep in mind that your function is just applying the resource on the controls on the form and it's ignoring nested controls. For example, if some controls are hosted on a panel, it will ignore them. To fix this issue, take a look at this post.
Note:
In general , I recommend restarting the form to apply new language, because the custom logic is not limited to ComboBox, you need specific logic for ComboBox, ListBox, ListView, TreeView, DataGridView, ToolStrip, ContextMenuStrip, MenuStrip, StatusStrip and maybe smoe other controls which I forget to mention.
In short, I believe saving the selected culture in a setting and then Application.Restart() and applying culture in Main method is what you are looking for.
When I add an item to a listbox in c#, if the string is > 4680 characters it displays as a blank line. I can still access the entire string from within the program.
Did I run up against a limit or am I doing something wrong?
The limit of text in a textbox is 64 KB worth of text. Here ya go.
displaying 4680+ characters for a single list item is not useful for the end user. You need to truncate the text or find another way to reference the text that is more user friendly.
I'm encountering a strange ListView problem and will do my best to explain it. I have a ListView with 4 columns, the last one being a message string of varying length. I have some functionality that will change the ListView item red if it contains certain keywords (fail, exception, ect).
I first noticed this issue when one item was red and I didn’t see any word in the column that would trigger the red coloring code. So, I had the Length of the incoming string prepending to the item and added a textbox that would display that column's text when selected. What I found was that the prepending length (actual length of incoming string) would be like 953, the extracted ListViewItem's Text length would be 960 (str length + prepended length info), but the text that would be in the text box's length was 253...
What's going on here? Its like all the text made it into the ListViewItem but it can't/won't show it all (and no, its not column width, I had it set to over 1000 in the above case).
Adding the ListViewItem and checking for error strings:
ListViewItem listItem = new ListViewItem(msg.Date);
// Add sub-items for Details view.
listItem.SubItems.Add(msg.Time);
listItem.SubItems.Add(msg.Thread);
listItem.SubItems.Add("L: " + msg.Message.Length + " " + msg.Message);
if (!msg.Message.Contains("FA_FAILCNT"))
{
if (msg.Message.Contains("fail", StringComparison.OrdinalIgnoreCase) ||
msg.Message.Contains("exception", StringComparison.OrdinalIgnoreCase) ||
msg.Message.Contains("db q", StringComparison.OrdinalIgnoreCase))
{
listItem.Font = new Font(listItem.Font, FontStyle.Bold);
listItem.ForeColor = Color.Red;
}
else
listItem.ForeColor = Color.Black;
}
Obviously its the last subitem thats giving me the issues (the one that gets msg.Message)
EDIT: Well crap, this explains it.... any ways around this?
You have already found the reason why not all of the text is displayed.
The best solution that I've found so far is to put the information in the tooltip so that the entire string is visible when the user hovers their mouse over the column - see Listview subitem text is not shown fully in the UI eventhough the length of the text is correct.
Another way I've seen this work is allowing users to copy the value of a cell. Although the displayed text is truncated, copying and pasting the cell value into another application allows you to view the full text.
I imagine that the only other "workaround" would involve writing your own control - alternatively I don't think the ListView control in WPF has this same limitation.
I want to use a control to notice users what are happening and what've done. It's like a multiline textbox, each line contains a notice, such as:
Connecting to database...done
Current datetime:
Inserting data into database 10/1000...done
Inserting data into database 20/1000...done
...
Inserted data into database
Current datetime:
I tried textbox, but it seems to be too complicated to manipulate many lines.
Is there a better control to do this? If textbox was the best choice, so how can I do this?
Thanks in advance!
I would use a listbox. Set it to SelectionMode.None. Add to the items collection. If you have enough lines to scroll off the screen you will need to adjust the scrollbar to the bottom manually. Do so by setting the listbox TopIndex to the number of lines - 1.
I've seen people use ListBoxes and TextBoxes. I usually use RichTextBoxes because then I can easily apply some simple styles and colouring, but it's probably overkill.
I found this method in one of my "just-playing-around" projects:
private void writeToLog(String text, SolidColorBrush color)
{
TextRange tr = new TextRange(logTextBox.Document.ContentEnd, logTextBox.Document.ContentEnd);
tr.Text = text;
tr.ApplyPropertyValue(TextElement.ForegroundProperty, color);
}