C# combobox with fonts using Datasource Visual Studio 2013 - c#

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);
}

Related

How to change the text-style of a ListView Header

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....);

Font does not change dynamically

I have a Windows Form containing a DataGridView which binds to a DataSet dynamically. In the form on the Button.Click event I am changing the DataGridView.Font appearance.
I tried the below code but it's not affecting the DataGridView. Only the header part is being changed.
Please recommend what I've done wrong in coding.
My Code
private void Btn_Language_Click(object sender, EventArgs e)
{
if(DGV_View.Font.Name == "Trebuchet MS")
{
DGV_View.Font = new System.Drawing.Font("NILKANTH", 12);
this.DGV_View.DefaultCellStyle.Font = new System.Drawing.Font("NILKANTH", 12);
}
else if(DGV_View.Font.Name == "NILKANTH")
{
DGV_View.Font = new System.Drawing.Font("Trebuchet MS", 11);
}
}
DataGridViewCellStyle style = new DataGridViewCellStyle();
style.Font = new Font(dataGridView.Font, FontStyle.Bold);
dataGridView.Rows[0].DefaultCellStyle = style;
Just saw it on the other site.

Removing textbox/label on button click C#

I am trying to remove textboxes and labels one by one by pressing a button.
I have a list of textboxes called inputTextBoxes.
Here is the code for adding :
private void onClickAdd(object sender, EventArgs e)
{
inputTextBoxes = new List<TextBox>();
Label label1 = new Label();
label1.Name = "label1";
label1.Text = "w" + i;
label1.Location = new System.Drawing.Point(5, 10 + (20 * i));
label1.Size = new System.Drawing.Size(30, 20);
this.Controls.Add(label1);
TextBox text1 = new TextBox();
text1.Name = "text1";
text1.Location = new System.Drawing.Point(35, 10 + (20 * i));
text1.Size = new System.Drawing.Size(25, 20);
inputTextBoxes.Add(text1);
this.Controls.Add(text1);
i++;
}
For removing I am trying this :
private void onClickRemove(object sender, EventArgs e)
{
foreach(TextBox text1 in inputTextBoxes)
{
this.Controls.Remove(text1);
}
}
But it removes only the last textbox added,clicking againg on the button doesn't do anything.
You are constantly creating a new list in your OnClickAdd() method:
inputTextBoxes = new List<TextBox>();
Try to check if the inputTextBoxes is null and only then do this line of code. Otherwise, just let the rest of the code run.
Also, remember about clearing the inputTextBoxes list after the onClickRemove() method finishes removing textboxes/labels.
You want to remove only one TextBox at a time, why do you need a foreach loop? just grab the last or first TextBox and if it is not null remove it from the Controls:
private void onClickRemove(object sender, EventArgs e)
{
var textBoxToRemove = inputTextBoxes.LastOrDefault();
// or
// var textBoxToRemove = inputTextBoxes.FirstOrDefault();
if (textBoxToRemove != null)
{
this.Controls.Remove(textBoxToRemove);
inputTextBoxes.Remove(textBoxToRemove);
}
}
Make sure you remove it from inputTextBoxes also so the next time you will ask to remove a TextBox it will not try to remove it again and go on to the next one.
Edit
#Piotr Nowak has pointed one more problem you have, you allocate a new list for inputTextBox every time you add a new TextBox, you should allocate the list only once when you create your class.
Remove this from onClickAdd method:
inputTextBoxes = new List<TextBox>();
And use this when you declare the list as a field it your class:
private readonly inputTextBoxes = new List<TextBox>();

How do I read the selections from Dynamically created combo boxes? in c#

I am trying to create a forms application in C# that will create several comboboxes, populate them with selectable items and then be able to detect what items were selected. I have the first two parts working: I can create the combo boxes, add the items to them, but when I try to write the code to read what items have been selected, I get errors because the controls don’t exist at build time..
public System.Windows.Forms.ComboBox AddNewSEPComboBox()
{
System.Windows.Forms.ComboBox SEPcbox = new System.Windows.Forms.ComboBox();
this.Controls.Add(SEPcbox);
SEPcbox.Top = A * 28;
SEPcbox.Left = 250;
string[] SEPSTAT = new string[]{"current (12.1.4013.4013), no changes made.", "not installed, no changes made.", "not installed, latest version (12.1.4013.4013) installed.", "outdated, updated to the latest version (12.1.4013.4013).", "outdated, no changes made."};
SEPcbox.Items.AddRange(SEPSTAT);
SEPcbox.Name = "SEPcbox" + A;
A++;
return SEPcbox;
Thanks in advance!
Manage your added controls by a list:
List<System.Windows.Forms.ComboBox> lstComboBoxAdded = new List<System.Windows.Forms.ComboBox>();
public System.Windows.Forms.ComboBox AddNewSEPComboBox()
{
System.Windows.Forms.ComboBox SEPcbox = new System.Windows.Forms.ComboBox();
SEPcbox.Top = A * 28;
SEPcbox.Left = 250;
SEPcbox.Location = new Point(20, A * 30);
string[] SEPSTAT = new string[] { "current (12.1.4013.4013), no changes made.", "not installed, no changes made.", "not installed, latest version (12.1.4013.4013) installed.", "outdated, updated to the latest version (12.1.4013.4013).", "outdated, no changes made." };
SEPcbox.Items.AddRange(SEPSTAT);
SEPcbox.Name = "SEPcbox" + A;
A++;
this.Controls.Add(SEPcbox);
lstComboBoxAdded.Add(SEPcbox);
return SEPcbox;
}
Then get your value like:
MessageBox.Show(lstComboBoxAdded.Where(m => m.Name == "SEPcbox" + A).First().Text);
Or manage Index/Value/Text by:
Dictionary<string, int> dicIndexSelected = new Dictionary<string, int>();
public System.Windows.Forms.ComboBox AddNewSEPComboBox()
{
System.Windows.Forms.ComboBox SEPcbox = new System.Windows.Forms.ComboBox();
SEPcbox.Top = A * 28;
SEPcbox.Left = 250;
SEPcbox.Location = new Point(20, A * 30);
string[] SEPSTAT = new string[] { "current (12.1.4013.4013), no changes made.", "not installed, no changes made.", "not installed, latest version (12.1.4013.4013) installed.", "outdated, updated to the latest version (12.1.4013.4013).", "outdated, no changes made." };
SEPcbox.Items.AddRange(SEPSTAT);
SEPcbox.Name = "SEPcbox" + A;
A++;
this.Controls.Add(SEPcbox);
dicIndexSelected.Add(SEPcbox.Name, -1);
SEPcbox.SelectedIndexChanged += new EventHandler(SEPcbox_SelectedIndexChanged);
return SEPcbox;
}
void SEPcbox_SelectedIndexChanged(object sender, EventArgs e)
{
dicIndexSelected[((System.Windows.Forms.ComboBox)sender).Name] = ((System.Windows.Forms.ComboBox)sender).SelectedIndex;
}
Then get your value like:
MessageBox.Show(dicIndexSelected["SEPcbox" + A].ToString());
You need to write an event handler exactly as you normally would, e.g.
private void ComboBoxes_SelectedIndexChanged(object sender, EventArgs e)
{
// ...
}
When you create the ComboBox control, you attach that method to the event, e.g.
var cbx = new ComboBox();
cbx.SelectedIndexChanged += ComboBoxes_SelectedIndexChanged;
Inside the event handler, the sender parameter refers to the object that raised the event, i.e. the ComboBox whose SelectedIndex just changed, e.g.
private void ComboBoxes_SelectedIndexChanged(object sender, EventArgs e)
{
var cbx = (ComboBox) sender;
var selection = cbx.Text;
MessageBox.Show(selection, "You chose...");
}

Adding a control in Datagridview

How to add a control in DataGridView? Using Button event. For example i want to create a new a row and column in DataGridView, this i want to happen through button control. How can i do it?
I am using C#.net and MS-Access.
Your question doesn't match it's title. The title asks about controls but the question is about rows and columns, I'm ignoring the title and I'm assuming it's an unbound DataGridView.
This MSDN link shows how to add rows and this shows how to add columns.
Here is a piece of code for adding a control into the gridview.
private void addNewRowButton_Click(object sender, EventArgs e)
{
this.DataGridViewIssue.Rows.Add();//This line will add a new button contol into the grid
}
private void deleteRowButton_Click(object sender, EventArgs e)
{
if (this.DataGridViewIssue.SelectedRows.Count > 0 &&
this.DataGridViewIssue.SelectedRows[0].Index !=
this.DataGridViewIssue.Rows.Count - 1)
{
this.DataGridViewIssue.Rows.RemoveAt(
this.DataGridViewIssue.SelectedRows[0].Index);
}
}
private void SetupLayout()
{
this.Size = new Size(1055, 800);
addNewRowButton.Text = "Add Row";
addNewRowButton.Location = new Point(10, 10);
addNewRowButton.Click += new EventHandler(addNewRowButton_Click);
deleteRowButton.Text = "Delete Row";
deleteRowButton.Location = new Point(100, 10);
deleteRowButton.Click += new EventHandler(deleteRowButton_Click);
buttonPanel.Controls.Add(addNewRowButton);
buttonPanel.Controls.Add(deleteRowButton);
buttonPanel.Height = 50;
buttonPanel.Dock = DockStyle.Bottom;
this.Controls.Add(this.buttonPanel);
}

Categories