Custom listbox wont display string completly c# - c#

Hi guys I am trying to rebrush individual items in a listbox, I went with listbox draw item event, somehow it works but when I add items to my listbox, only string "b" is added and never the + "hi" part, I could write whatever I want or add whatever I want, only string b will be printed.
Not using draw mode and sticking with normal listbox obviously fixes the issue, so I guess it must be related to draw item event, but I cant figue out what exactly does this, I appreciate any help
listBox3.DrawMode = DrawMode.OwnerDrawFixed;
private async void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
foreach (string b in liIDs)
{
listBox3.Invoke((MethodInvoker)delegate
{
listBox3.Items.Add(b + "hi");
listBox3.Update();
});
}
private void listBox3_DrawItem(object sender, DrawItemEventArgs e)
{
try
{
e.DrawBackground();
Brush myBrush = Brushes.White;
myBrush = Brushes.Red;
e.Graphics.DrawString(((ListBox)sender).Items[e.Index].ToString(),
e.Font, myBrush, e.Bounds, StringFormat.GenericDefault);
e.DrawFocusRectangle();
}
catch
{
}
}

I could only reproduce using items with values width larger than the list box width.
If thats the case you need to set the HorizontalScrollbar propertie to True and HorizontalExtent value

Related

Grey out text in a listbox

Is there a toolbox object that is like a listbox but each individual item can have a different font colour? I'm trying to make a mod manager of sorts and want to grey out the text for those mods that are uninstalled.
Try this:
private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
{
e.Graphics.DrawString(Convert.ToString(listBox1.Items[e.Index]), new Font("Aerial", 8), Brushes.Gray, new Point(0, 0));
e.DrawFocusRectangle();
}
For this to work, change the DrawMode of the Listbox to OwnerDrawFixed.
Also, if you want to select an item in a combobox, try something like this:
comboBox1.SelectedIndex = 0;

Change current color in a richTextBox?

I would like to make a program where you can type in a richTextBox and then change the color.
So I tried this.
private void redFontColor_Click_1(object sender, EventArgs e)
{
richTxtBox.FrontColor = Color.Red;
}
But when I click the redFontColor button all the text in the richTextbox changes to red. So I tried to change the the color of each character individually.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Color currentColor = Color.Black;
private void redFontColor_Click_1(object sender, EventArgs e)
{
currentColor = Color.Red;
}
private void richTxtBox_TextChanged(object sender, EventArgs e)
{
if (textBox.SelectionStart != 0)
{
richTextBox.Select(textBox.SelectionStart - 1, 1);
richTextBox.SelectionColor = currentColor;
}
}
}
But when I now type something the color will change but when you enter a character it will be selected like this:
How could I make this work so the char isn't selected each time I type something? Or do I have to search for another method to do this?
Basically richTxtBox.FrontColor = Color.Red; will change the color of all text to Red, but you requirement is to change only the color of selected text, for that you need to use, richTextBox1.SelectionColor = Color.Red; which will change the color of only selected text.
You can decide which portion of the text need to be selected by using SelectionStart and SelectionLength. it is purely working on the basics of the index.
The mentioned problem of selecting the typed text in richTextBox1_TextChanged can be avoid by using this snippet
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
if (richTextBox1.SelectionStart != 0)
{
int length = richTextBox1.Text.Length;
richTextBox1.Select(richTextBox1.SelectionStart - 1, 1);
richTextBox1.SelectionColor = Color.Red ;
richTextBox1.SelectionStart = length;
}
}
Apart from other answers here i have a magic box, which will changes the colors based on text.
And this can be achieved by using the following code:
private void button1_Click(object sender, EventArgs e)
{
int selectionStart = 0;
foreach (var item in richTextBox1.Text.Split(' '))
{
Color rgb = Color.FromName(item);
richTextBox1.SelectionStart = selectionStart;
richTextBox1.SelectionLength = item.Length;
richTextBox1.SelectionColor = rgb;
selectionStart += item.Length + 1;
}
}
As for your code: You are selecting a length of 1, i.e. the last character and you now see it highlighted. This is all not necessary. If you want to set colors or other formatting to text you enter simply do this:
Set the SelectionStart to the point he text gets entered, for example the end of the Text
Set the SelectionLength to 0
Set the formatting you want.
It will carry over to all text that you enter; make sure no line break (which in a RTB really means a new paragraph) slips in, as it will break the automatic carrying over. This all works pretty much like it does in Word..
Btw: Do not call a RichTextBox a Textbox; yes, they are related but still..
Also: We need to understand the difference between highlighting and selecting!
Selections are meant to format text portions.
Highlighting happens along the way and looks like it is set to look in the system settings.
Here is an example with all you need to get started:
private void panel1_MouseClick(object sender, MouseEventArgs e)
{
if ( richTextBox1.SelectionLength == 0)
richTextBox1.SelectionStart = richTextBox1.Text.Length;
Color c = ((Bitmap)panel1.BackgroundImage).GetPixel(e.X, e.Y);
if (e.Button.HasFlag(MouseButtons.Left))
{
richTextBox1.SelectionColor = c;
}
else
{
richTextBox1.SelectionBackColor = c;
}
}
Pick a nice color palette and display in in a Panel.BackgroundImage; the code the MouseClick event. Done.
You can keep typing and when you left-click a color the text color will start to appear in the color. When you right-click it the backcolor will change. When there is a selection already it will change its color.
For a full formatting rtb you will want to add other things like font style size etc..
Note: No need to code the TextChanged event for this.

No row indentation for items in ListView

I'm currently working on some software and the customer is dead-set on a specific UI change that has been giving me some trouble:
I would like items in a ListView to not have any indentation. To illustrate I changed the backcolor of the ListView and the items.
Now, the little piece to the left of each item should also be white. Any ideas?
You can set the OwnerDraw property of ListView to true and using DrawItem, DrawColumnHeader and DrawSubItem draw the list view yourself.
For example:
private void listView1_DrawItem(object sender, DrawListViewItemEventArgs e)
{
e.Graphics.DrawString(e.Item.Text, e.Item.Font, Brushes.Black,
new Rectangle(e.Bounds.Left-2, e.Bounds.Top, e.Bounds.Width, e.Bounds.Height));
}
private void listView1_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
{
e.DrawDefault = true;
}
private void listView1_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
{
if(e.ColumnIndex>0)
e.DrawDefault = true;
}
Note:
The above rendering is just an example and shows you how you can draw item text in desired location for example using using Graphics.DrawString.
Also it shows you how to set e.DrawDefault = true; to perform default rendering.
The first subitem of each ListViewItem object represents the parent item itself
To avoid issues with graphics flickering when owner drawing, override the ListView control and set the DoubleBuffered property to true.
To learn more, read documents of OwnerDraw property of ListView control.

Apply different properties on specific items in listbox

I fill a listbox listBoxHome from a dictionary dictionaryHome :
dictionaryHome.Add(item.Id, item.Name);
listBoxHome.DataSource = new BindingSource(dictionaryHome, null);
listBoxHome.DisplayMember = "Value";
listBoxHome.ValueMember = "Key";
I also use the following code to be able only first 5 items to be selectable
private void listBoxHome_SelectedIndexChanged(object sender, EventArgs e)
{
InvertMySelection(listBoxHome, listBoxAway);
//make only first5 selectable
for (int i = 5; i < listBoxHome.Items.Count; i++)
{
if (listBoxHome.GetSelected(i) == true)
listBoxHome.ClearSelected();
}
}
I want to apply a different color to the first 5 items and different color the other items.
Or maybe a transparent panel that shows difference from the first 5 items and the other items. Also I want to draw a line inside the listbox as shown in the image. Any suggestion?
EDIT:
Adding Luc Morin's code the result shown in the following picture
Is there a way to show only the text and not the id(as was before)?The id is used in the back.
First you need to set the DrawMode to OwnerDrawFixed in the Windows Forms Designer property grid.
Then, add an event handler to the ListBox.DrawItem event, something along those lines:
private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
{
// Draw the background of the ListBox control for each item.
e.DrawBackground();
// Define the default color of the brush as black.
Brush myBrush = Brushes.Black;
// Determine the color of the brush to draw each item based
// on the index of the item to draw.
if (e.Index < 3)
{
myBrush = Brushes.Red;
}
// Draw the current item text based on the current Font
// and the custom brush settings.
e.Graphics.DrawString(((KeyValuePair<int, string>)listBox1.Items[e.Index]).Value,
e.Font, myBrush, e.Bounds, StringFormat.GenericDefault);
// If the ListBox has focus, draw a focus rectangle around the selected item.
e.DrawFocusRectangle();
}
Adapt to your specific needs.
Code adapted from MSDN sample at: http://msdn.microsoft.com/en-us/library/system.windows.forms.listbox.drawitem(v=vs.110).aspx
Cheers
EDIT: In order to prevent selection of items, handle the ListBox.SelectedIhanged, something like this:
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if(listBox1.SelectedIndex >=3)
{
listBox1.SelectedIndex = -1;
listBox1.Invalidate();
}
}
EDIT 2: When binding to a dictionary, the ListBox.Items collection actually contains KeyValuePair objects instead of just strings. I updated the code to account for this. My example assumes the Key is an int and the Value is a string.

Draw Simple Circle in List box in C#.Net Desktop Application

i want to draw simple circle of different category size of circle come form database and different size in c#.net for desktop for winforms ..
as you saw me how to draw circle using listbox now i want to fill color in List box each circle using another List box when color is defined ....it is multiple color also we can apply .. please help me in this..
Set DrawMode property and handle DrawItem event of ListBox,
private void Form1_Load(object sender, EventArgs e)
{
listBox1.DrawMode = DrawMode.OwnerDrawVariable;
listBox1.Items.Add("One");
listBox1.Items.Add("Two");
listBox1.Items.Add("Three");
listBox1.DrawItem += new DrawItemEventHandler(listBox1_DrawItem);
}
void listBox1_DrawItem(object sender, DrawItemEventArgs e)
{
ListBox l=sender as ListBox;
e.DrawBackground();
e.DrawFocusRectangle();
e.Graphics.DrawEllipse(Pens.Blue, new Rectangle(1, 1+e.Index * 15, 100, 10));
e.Graphics.DrawString(l.Items[e.Index].ToString(), new Font(FontFamily.GenericSansSerif,9, FontStyle.Regular), Brushes.Red , e.Bounds);
}

Categories