How to change the text-style of a ListView Header - c#

This is my code to only make the Header of the listView bold, but it is not working, because not only the Header, but all the items are getting bold.
listView.Columns[0].ListView.Font = new Font(listView.Columns[0].ListView.Font, FontStyle.Bold);
Anyone has a solution?

Unfortunately you cannot change the header font. But you can change the font for each individual list item. The simple but hacky approach is to set ListView.Font to the bold font and change the font of every ListItem.Font to the default font.
listView.Font = _headerFont;
foreach(ListViewItem item in listView.Items)
{
item.Font = SystemFonts.DefaultFont;
}
Alternatively for full control set the OwnerDraw property to true and handle both DrawColumnHeader and DrawItem events like below:
public partial class Form1 : Form
{
private readonly Font _headerFont = new Font(SystemFonts.DefaultFont, FontStyle.Bold);
public Form1()
{
InitializeComponent();
listView.OwnerDraw = true;
listView.DrawColumnHeader += DrawColumnHeader;
listView.DrawItem += DrawItem;
}
private void DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
{
// Draw default background
e.DrawBackground();
// Draw text in a different font
TextRenderer.DrawText(e.Graphics,
e.Header.Text,
_headerFont,
e.Bounds,
SystemColors.ControlText,
TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
}
private void DrawItem(object sender, DrawListViewItemEventArgs e)
{
// Use defaults for Items
e.DrawDefault = true;
}
}
The example above shows how it works, but in a real world application you also have to draw dependent on the item's state like in the more comprehensive example in the .NET docs

Using the answer of Christian Held, I come up with the next solution:
Put this in the constructor of the form:
List<ColumnHeader> columns = new List<ColumnHeader>
{
new ColumnHeader{Text = "ColumnOne", TextAlign = HorizontalAlignment.Left},
new ColumnHeader{Text = "ColumnTwo", TextAlign = HorizontalAlignment.Left},
new ColumnHeader{Text = "ColumnThree", TextAlign = HorizontalAlignment.Left}
};
MyListView.Font = new Font(SystemFonts.DefaultFont, FontStyle.Bold);
columns.ForEach(col => MyListView.Columns.Add(col));
MyListView.View = View.Details;
After that, when you fill with data your ListView, you must set the font for every record added:
foreach (MyData myData in MyDatas){
listViewItem = new ListViewItem(new string[]
{
myData.Data1,
myData.Data2,
myData.Data3
});
listViewItem.Font = SystemFonts.DefaultFont;
MyListView.Items.Add(listViewItem);
}
And it works fine for me. If you want to change the backcolor or other things in the font of the data, just change the SystemFonts.DefaultFont for some font that you like, something like
var myFont = new Font(...your details here....);

Related

How can i change listView ColumnHeader text color?

In the form1 constructor
listView1.Scrollable = true;
listView1.View = View.Details;
ColumnHeader header = new ColumnHeader();
header.Text = "Files are ready";
header.Name = "col1";
listView1.Columns.Add(header);
listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
I want to change the color of "Files are ready" to Red.
So I tried with this event:
private void listView1_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
{
using (var sf = new StringFormat())
{
sf.Alignment = StringAlignment.Center;
using (var headerFont = new Font("Microsoft Sans Serif", 9, FontStyle.Bold))
{
e.Graphics.FillRectangle(Brushes.Pink, e.Bounds);
e.Graphics.DrawString(e.Header.Text, headerFont,
Brushes.Black, e.Bounds, sf);
}
}
}
Tried to change both Brushes to Red but it didn't change anything.
You probably misssed to set the OwnerDraw property of your listView1 to true.
This property indicates that you want to draw parts of the ListView by your own code instead of the original ListView methods. Without it events like DrawColumnHeader, DrawItem and DrawSubItem will not be raised by the ListView.
For the columns you do not want to draw by yourself set e.DrawDefault to true. And use e.DrawBackground() to draw the background of the header if you only want to change the text color:
private void listView1_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
{
if (e.ColumnIndex != myColumnIndex)
{
e.DrawDefault = true; // tell the ListView to draw this header
return;
}
e.DrawBackground();
// draw your text as you did in your code
// except the FillRectangle since the background is
// now already drawn
}
But if you do set listView1.OwnerDraw to true, the ListView will ask you for everything: the headers, the items and the subitems. So you will need to subscribe to DrawItem and DrawSubItem events, too and tell the ListView explicitly that you want it to draw those things by itself:
listView1.DrawItem += (sender, e) => { e.DrawDefault = true; };
listView1.DrawSubItem += (sender, e) => { e.DrawDefault = true; };

Can't raise click event of a UserControl in C#

I have a dynamically added UserControl:
var listItem = new ListItem(/* arguments */);
listItem.Click += SetListItemColor;
panel.Controls.Add(listItem); // "panel" is FlowLayoutPanel
SetListItemColor:
private void SetListItemColor(object sender, EventArgs e)
{
var listItem = (ListItem)sender;
if (listItem.BackColor == Color.LightGray)
{
listItem.BackColor = Color.White;
}
else
{
listItem.BackColor = Color.LightGray;
}
}
No change to the color happens when I click on the UserControl. However, for test purpose, I tried to change the event to EnabledChangedand change the Enabled property, the color does change:
var listItem = new ListItem(/* arguments */);
listItem.Enabled = false;
listItem.EnabledChanged += SetListItemColor;
listItem.Enabled = true;
panel.Controls.Add(listItem);
What's the problem?
EDIT:
Since docking doesn't work in a FlowLayoutPanel, suggest setting the size of your control to the size of the panel. Set the ListItem margins to empty as below to get maximum fill. For debugging set the backcolor different to make sure you can see it:
var listItem = new ListItem(/* arguments */);
listItem.BackColor = Color.Yellow; // Debugging only
listItem.Margin = Padding.Empty;
listItem.Size = panel.Size;
listItem.Click += SetListItemColor;
Note that if the control is resized you will need to resize your ListItem again.

C# combobox with fonts using Datasource Visual Studio 2013

I have a form with a ComboBox on it. I would like to fill this with the available fonts on the system and make the user to select one of these options.
I looked for different approaches to achieving this and I used this question and the answer to load the ComboBox with all the fonts: Fill ComboBox with List of available Fonts
This is my code currently that works:
form.comboBox2.Items.Clear();
System.Drawing.Text.FontCollection fontcoll = new System.Drawing.Text.InstalledFontCollection();
foreach (FontFamily font in fontcoll.Families)
{
form.comboBox2.Items.Add(font.Name);
}
But now I am trying to use instead the DataSource property and I imported the System.Drawing.Text.InstalledFontCollection into my project as datasource.
Here is the code of the designer:
//
// comboBox2
//
this.comboBox2.DataSource = this.installedFontCollectionBindingSource;
this.comboBox2.FormattingEnabled = true;
this.comboBox2.Location = new System.Drawing.Point(16, 44);
this.comboBox2.Name = "comboBox2";
this.comboBox2.Size = new System.Drawing.Size(144, 21);
this.comboBox2.TabIndex = 9;
this.comboBox2.SelectedIndexChanged += new System.EventHandler(this.comboBox2_SelectedIndexChanged);
Then in my initialization of the form, I have this to set selected the font name to Times New Roman as default:
form.comboBox2.Text = "Times New Roman"
I thought this would be enough to fill the ComboBox and select Times New Roman but apparently is not enough. It displays Times New Roman alright, but the box is empty.
What I would like to get help with:
1) How to make the datasource to populate the ComboBox?
2) Is there a simple way to force the user to select one of the entries from the box and not type in some other value that is not in the list (similarly to the "MatchRequired" property in VBA userforms)?
Thanks in advance.
You should first get a list of all installed font families and then set the list as DataSource of ComboBox. Also you can set DropDownStyle of combo box to DropDownList.
private void Form1_Load(object sender, EventArgs e)
{
this.comboBox1.DataSource = new InstalledFontCollection().Families;
this.comboBox1.DisplayMember = "Name";
this.comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
this.comboBox1.SelectedIndexChanged += comboBox1_SelectedIndexChanged;
}
You can get selected font family from SelectedValueof ComboBox. For example:
void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (this.comboBox1.SelectedValue != null)
this.Font = new Font((FontFamily)this.comboBox1.SelectedValue, this.Font.Size);
}
You can use :
private void Form1_Load(object sender, EventArgs e)
{
FontFamily[] fontArray = FontFamily.Families;
foreach (FontFamily font in fontArray)
{
comboBox1.Items.Add(font.Name);
}
comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
}
With a property DropDownStyle, users are limited to choices in the list.
For example if you want to assign font with size 14 to the Label :
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
label1.Font = new Font(comboBox1.Text , 14);
}

How to define an event to a .cs class that is returning a collection of labels?

I have a method that is returning a collection of Labels although i am able to set an properties of label but i want to define the paint event of label so that i can draw the items there in some format.
public List<Label> drawLabel()
{
lstLable = new List<Label>();
foreach (cOrderItem item in currOrder.OrderItems)
{
_lbl = new Label();
_lbl.Width = 200;// (int)CanvasWidth;
_lbl.BackColor = Color.AliceBlue;
_lbl.Text = item.ProductInfo.ProductDesc;
_lbl.Height = 20;
_lbl.Dock = DockStyle.Top;
_lbl.Paint()////this is the event i want to define for drawign purpose.
lstLable.Add(_lbl);
}
return lstLable;
}
I am returning this collection to a form where i am taking each label and adding to a panel.
It's not quite clear if you mean winforms, wpf or webforms, but in winforms just use the Control.Paint-event as any other event:
public List<Label> drawLabel()
{
lstLable = new List<Label>();
foreach (cOrderItem item in currOrder.OrderItems)
{
_lbl = new Label();
_lbl.Width = 200;// (int)CanvasWidth;
_lbl.BackColor = Color.AliceBlue;
_lbl.Text = item.ProductInfo.ProductDesc;
_lbl.Height = 20;
_lbl.Dock = DockStyle.Top;
//this is the event i want to define for drawign purpose.
_lbl.Paint += new PaintEventHandler(LblOnPaint);
lstLable.Add(_lbl);
}
return lstLable;
}
// The Paint event method
private void LblOnPaint(object sender, PaintEventArgs e)
{
// Example code:
var label = (Label)sender;
// Create a local version of the graphics object for the label.
Graphics g = e.Graphics;
// Draw a string on the label.
g.DrawString(label.Text, new Font("Arial", 10), Brushes.Blue, new Point(1, 1));
}
You can subscribe to the paint event of Label class
_lbl.Paint+=yourCustomPaintMethod;
use ObservableCollection instead of List
You can also learn to use Reactive Extensions.
I would subclass the Label control and override the OnPaint Method.

How to retain colors of texts in rich text box?

I put some colored text to my rich text box my using the following code:
richTextBox1.SelectionColor = Color.Blue;
richTextBox1.SelectedText = "Name";
richTextBox1.SelectionColor = Color.Black;
richTextBox1.SelectedText = ": some message.";
But when I hide the richtextbox from the user by setting its parent property to null (I have this panel that holds different rich text boxes from time to time), and put it back, the rich text box does not retain the text colors I applied to it. All texts becomes black.
Update: I tried an experiment. In my main program, I have a UserControl (which has a Panel) where I put a RichTextBox with colored text. I have many RichTextBoxes which I store to a HashTable.
So when I need a RichTextBox, I retrieve it from my HashTable, put some colored text into it, put it inside my UserControl's Panel and finally put my UserControl to my program's Form. My UserControl can actually be temporarily removed from the program's Form when a user clicks on a button, I do using Controls.Remove(). To put it back into my Form, I use Controls.Add(). The problem is, when the UserControl is added back, the RichTextBox's texts are not colored anymore.
I tried doing something similar in another experimental program.
public partial class Form1 : Form
{
private chat.UserControl1 ChatWindowKuno = new chat.UserControl1();
private Hashtable htChatLogs = new Hashtable(30);
public Form1()
{
InitializeComponent();
createRTBox();
}
private void createRTBox()
{
RichTextBox richTextBox1 = new RichTextBox();
richTextBox1.Multiline = true;
richTextBox1.Dock = DockStyle.Fill;
richTextBox1.ReadOnly = true;
richTextBox1.BackColor = SystemColors.Window;
htChatLogs.Add("Basta", richTextBox1);
}
private void button1_Click_1(object sender, EventArgs e)
{
if (ChatWindowKuno.Parent == null)
ChatWindowKuno.Parent = tabPage2;
else
ChatWindowKuno.Parent = null;
}
private void button2_Click(object sender, EventArgs e)
{
// Clear all text from the RichTextBox;
RichTextBox richTextBox1 = (RichTextBox)htChatLogs["Basta"];
richTextBox1.Clear();
richTextBox1.SelectionFont = new Font("Segoe UI", 8.25F, FontStyle.Regular);
richTextBox1.SelectionColor = Color.Blue;
richTextBox1.SelectedText = "Xel";
richTextBox1.SelectionColor = Color.Black;
richTextBox1.SelectedText = ": Listening to Be My Last by Utada Hikaru.";
richTextBox1.SelectionColor = Color.Gray;
richTextBox1.SelectionFont = new Font("Segoe UI", 8.25F, FontStyle.Italic);
richTextBox1.SelectedText = " [5:56pm] \n";
richTextBox1.SelectionColor = Color.Gray;
richTextBox1.SelectedText = "[5:56pm] ";
richTextBox1.SelectionFont = new Font("Segoe UI", 8.25F, FontStyle.Regular);
richTextBox1.SelectionColor = Color.Blue;
richTextBox1.SelectedText = "Xel";
richTextBox1.SelectionColor = Color.Black;
richTextBox1.SelectedText = ": Listening to Be My Last by Utada Hikaru.";
}
private void button3_Click(object sender, EventArgs e)
{
RichTextBox richTextBox1 = (RichTextBox)htChatLogs["Basta"];
ChatWindowKuno.ChatLog = richTextBox1;
}
}
The ChatLog property of usercontrol1 is this:
public Control ChatLogPanel
{
get
{
return panel1.Controls[0];
}
set
{
panel1.Controls.Clear();
panel1.Controls.Add(value);
}
}
I click the 3 buttons randomly in my experimental program, but the text colors are retained.
You shouldn't use Parent property to hide, but Visible property instead.
If you hide a richtextbox using richTextBox.Visible = false it keeps its formatting (tested).
EDIT :
as discussed in the comments below, I suggest you to use only one RichTextBox and store several Rtf strings in a Dictionary (or Hashtable) to mimic the existence of different RichTextBox'es.
An example of what I mean can be found Here

Categories