Winform how to remove Item from combobox using SelectedValue? - c#

public void Fill()
{
cmb1.DataSource = dt;
cmb1.DisplayMember = "Name";
cmb1.ValueMember = "ID";
}
public void Remove()//by Text
{
string selectedItem ="Jack";
cmb1.Items.Remove(selectedItem );
}
public void Remove()//by Value
{
string selectedvalue ="10";
cmb1.Items.RemoveAt(selectedvalue);
}
This Code used but not worked.
Not Remove Using Value or Text.Or Any Other Methods to fill combobox without DataSource.

You can do the following because you are using a data source:
DataTable dt = (DataTable)cmb1.DataSource;
dt.Rows.RemoveAt(cmb1.SelectedIndex);

Try something like this:
class Student {
public int ID{get;set;}
public string Name { get; set; }
// You override this method depending in what you want to show on the comboBox as text
public override string ToString()
{
return Name;
}
}
private void fillComboBox(List<Student> students)
{
// We manually fill the comboBox Items; The displayed text is going to be define by the ToString() method this object has define
students.ForEach(x => cmb1.Items.Add(students));
}
private void button1_Click(object sender, EventArgs e)
{
// We can remove the items by just doing this
cmb1.Items.Remove(cmb1.SelectedItem);
}

Related

How we can refresh items text in ListBox without reinserting it?

I have the class TestClass that has ToString overriden (it returns Name field).
I have instances of TestClass added into ListBox and at certain point I need to change Name of one of this instances, how then I can refresh it's text in ListBox?
using System;
using System.Windows.Forms;
namespace TestListBox
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
listBox1.Items.Add(new TestClass("asd"));
listBox1.Items.Add(new TestClass("dsa"));
listBox1.Items.Add(new TestClass("wqe"));
listBox1.Items.Add(new TestClass("ewq"));
}
private void button1_Click(object sender, EventArgs e)
{
((TestClass)listBox1.Items[0]).Name = "123";
listBox1.Refresh(); // doesn't help
listBox1.Update(); // same of course
}
}
public class TestClass
{
public string Name;
public TestClass(string name)
{
this.Name = name;
}
public override string ToString()
{
return this.Name;
}
}
}
try
listBox1.Items[0] = listBox1.Items[0];
I have encountered this same issue and tried all sorts of different ways to tr y to get the displayed text of an item to actually reflect the underlying item value.
After going through all the available properties I found this to be the simplest.
lbGroupList.DrawMode = DrawMode.OwnerDrawFixed;
lbGroupList.DrawMode = DrawMode.Normal;
It triggers the appropriate events within the control to update the displayed text.
Your Testclass needs to implement INotifyPropertyChanged
public class TestClass : INotifyPropertyChanged
{
string _name;
public string Name
{
get { return _name;}
set
{
_name = value;
_notifyPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void _notifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public TestClass(string name)
{
this.Name = name;
}
public override string ToString()
{
return this.Name;
}
}
However this only works if you use Columns that do not rely on the ToString() but bind the property Name
This can be done by altering your code:
somewhere in class declare
BindingList<TestClass> _dataSource = new BindingList<TestClass>();
In initializeComponent write
listBox1.DataSource = _dataSource;
Then do all operations on _dataSource instead of Listbox.
You could use a BindingList:
items = new BindingList<TestClass>( );
listBox1.DataSource = items;
listBox1.DisplayMember = "_Name";
Then to refresh the list call:
items.ResetBindings( );
edit: Also don't forget to create a get Property for Name
public string _Name
{
get { return Name; }
set { Name= value; }
}
I use the following code:
public static void RefreshItemAt (ListBox listBox, int itemIndex)
{
if (itemIndex >= 0)
{
Rectangle itemRect = listBox.GetItemRectangle(itemIndex);
listBox.Invalidate(itemRect);
listBox.Update();
}
}

ListBox forcing update of items

I created a ListBoxItem where I have a property Name and override ToString() to give back name. That works nicely when I add new items.
But now I need to force the ListBox to update the labels when I change the name of my ship. I thought Refresh or Update would do that but that doesn't work.
I might be missing something very easy here.
public class ShipListBoxItem
{
public ListBox Parent { get; set; }
public ShipType Ship { get; set; }
public ShipListBoxItem()
{
Ship = new ShipType();
}
public ShipListBoxItem(ShipType st)
{
Ship = st;
}
public override string ToString()
{
return Ship.Name;
}
public void UpdateListBox()
{
Parent.Refresh(); //My problem is here. Update doesn't work either.
}
public static ShipListBoxItem AddToListBox(ListBox lb, ShipType ship)
{
ShipListBoxItem li = new ShipListBoxItem(ship);
li.Parent = lb;
lb.Items.Add(li);
return li;
}
}
If you use a List<T> as the DataSource for the listbox it is pretty easy to have changes to items show up. It also means there is no real reason to have a special class for adding a ShipListBoxItem to a ListBox, your basic Ship class may work:
class ShipItem
{
public enum ShipTypes { BattleShip, Carrier, Destroyer, Submarine, Frigate };
public ShipTypes Ship { get; set; }
public string Name { get; set; }
public ShipItem(string n, ShipTypes st)
{
Name = n;
Ship = st;
}
public override string ToString()
{
return String.Format("{0}: {1}", Ship.ToString(), Name);
}
}
The form related stuff:
private void Form1_Load(object sender, EventArgs e)
{
// add some ships
Ships = new List<ShipItem>();
Ships.Add(new ShipItem("USS Missouri", ShipTypes.BattleShip));
Ships.Add(new ShipItem("USS Ronald Reagan", ShipTypes.Carrier));
lb.DataSource = Ships;
}
private void button1_Click(object sender, EventArgs e)
{
// change a ship name
lb.DataSource = null; // suspend binding
this.Ships[0].Name = "USS Iowa";
lb.DataSource = Ships; // rebind
lb.Refresh();
}
As an alternative, you can also tell the Listbox to use a specific property for the display using DisplayMember:
lb.DataSource = Ships;
lb.DisplayMember = "Name";
This would use the Name property in the listbox instead of the ToString method. If your list is changing a lot, use a BindingList instead. It will allow changes to the list show up in the ListBox as you add them without toggling the DataSource.
Try this
ListBox.RefreshItems()
msdn
EDIT: You can use an extended class like this:
public class FooLisBox : System.Windows.Forms.ListBox
{
public void RefreshAllItems()
{
RefreshItems();
}
}
private void button1_Click(object sender, EventArgs e)
{
(listBox1.Items[0] as ShipListBoxItem).Ship.Name = "AAAA";
listBox1.RefreshAllItems();
}
I managed to solve my problem.
Mostly, thanks Jose M.
I ran into a problem however. RefreshItems() triggers OnSelectedIndexChanged()
so my overridden class looks like this
public class MyListBox : ListBox
{
public bool DoEvents{ get; set; } // Made it public so in the future I can block event triggering externally
public MyListBox()
{
DoEvents = true;
}
public void RefreshAllItems()
{
SuspendLayout();
DoEvents = false;
base.RefreshItems(); // this triggers OnSelectedIndexChanged as it selects the selected item again
DoEvents = true;
ResumeLayout();
}
// I only use this event but you can add all events you need to block
protected override void OnSelectedIndexChanged(EventArgs e)
{
if (DoEvents)
base.OnSelectedIndexChanged(e);
}
}

List Box with BindingSource containing objects not showing displayName C#

I have found many answered questions on here explaining how to do this when the objects are created as part of the data source but my list box is just displaying "SharePointXMLBuilder.Farm" (Namespace.class) and not the selected DisplayName?
I dont know what I am doing wrong can anyone help please.
I have a list box with a data source as a databinding control and I am adding my created objects(Farm) to the databinding(farmListBindingSource) which all works fine, I just cant get the list to show the property I want it to.
Form: (loads another form takes input and returns to create object from Farm class)
private void CreateNewFarm_Click(object sender, EventArgs e)
{
FarmInput input = new FarmInput();
input.ShowDialog();
Farm nFarm = new Farm();
nFarm.location = input.inputLocation.ToString();
nFarm.identifier = input.inputType.ToString();
nFarm.environment = input.inputEnvironment.ToString();
this.farmListBindingSource.Add(nFarm);
this.testReturnTextBox.Text = nFarm.friendlyName;
}
private void MainForm_Load(object sender, EventArgs e)
{
this.FarmListBox.DisplayMember = "friendlyName";
this.testReturnTextBox.Text = "Form Loaded....";
}
Class:
namespace SharePointXMLBuilder
{
class Farm
{
private string farmLocation;
private string farmIdentifier;
private string farmEnvironment;
private string farmFriendlyName;
//private List<Server> farmServers;
//properties
public string friendlyName
{
get { return farmFriendlyName; }
set { farmFriendlyName = value; }
}
public string location
{
get { return farmLocation;}
set { farmLocation = value; this.buildFriendlyName(); }
}
public string identifier
{
get { return farmIdentifier; }
set { farmIdentifier = value; this.buildFriendlyName(); }
}
public string environment
{
get { return farmEnvironment; }
set { farmEnvironment = value; this.buildFriendlyName(); }
}
//constructor
public Farm()
{
}
//methods
public void AddServer(string s)
{
Server nServer = new Server(s);
// farmServers.Add(nServer);
}
public void buildFriendlyName()
{
this.friendlyName = this.location + " " + this.identifier + " " + this.environment;
}
}
}
Maybe you are not calling this function: buildFriendlyName() for each object in the list prior to binding?
In your buildfriendlyname() method set your private string farmFriendlyName insted of setting the property value friendlyname
Ok, so I tried to manually add DisplayMember in the designer and it wouldn't hold the value, as soon as I removed the DataSource it allowed DisplayMember to be populated so I changed the CreateNewFarm_Click to add the object to farmListBox.Items and when I re-ran the code it was fine.
It appears that you cannot use DisplayMember if you are pulling the objects from a DataSource.

Want to avoid default zero value

I have the a class in my application. It has been bound to winform textbox controls. But the textbox which is bound to BookingNo property, always shows zero (0). But i want the textbox keep empty. Is there any way to do it? Here is my code snippet.
public class Booking
{
private int pBookingNo;
private string pCustomerName;
private string pAddress;
public int BookingNo
{
get { return pBookingNo; }
set
{
if (!value.Equals(pBookingNo))
{
pBookingNo = value;
}
}
}
public string CustomerName
{
get { return pCustomerName; }
set
{
if (!value.Equals(pCustomerName))
{
pCustomerName = value;
}
}
}
public Booking() { }
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
AddDataBindings();
}
private void AddDataBindings()
{
bsBooking.DataSource = typeof(Booking);
txtBookingNo.DataBindings.Add("Text", bsBooking, "BookingNo", true, DataSourceUpdateMode.OnPropertyChanged, null, "G", GlobalVariables.CurrentCultureInfo);
txtCustomerName.DataBindings.Add("Text", bsBooking, "CustomerName");
}
}
The default value of an Integer is 0, so you have to wrap it into some other object, which supports values other than 0, like
public int? BookingNo { get; set; }
You can use Nullable Type
public int? pBookingNo
{
get;
set;
}
Link : http://msdn.microsoft.com/fr-fr/library/1t3y8s4s(v=vs.80).aspx
You could use custom formatting for the binding by adding a handler to the Format event (http://msdn.microsoft.com/en-us/library/system.windows.forms.binding.format.aspx) and return an empty string when the value is zero. But you wouldn't be able to tell whether the value is actually zero or it just hasn't been set already, in which case using the int? approach suggested by #Grumbler85 is better.
what´s about:
textBox1.BindingContextChanged += new EventHandler(BindingContext_Changed);
private void BindingContext_Changed(object sender, EventArgs e)
{
TextBox txtBox = (TextBox)sender;
if (txtBox.Text == "0"){
txtBox.Text = "";
}
}
don´t know if it works, just an idea.

How do I setup a multi value dropdownlist from a list collection

How to setup a multi value dropdownlist from a list collection...
Datasource: Listcollection which contains ColorCode and Description...
how to I setup a dropdown with Colorcode-Description like ORG-orange...
then how to capture these selected value as colorcode only by removing description for update purpose...
Now I am doing like this...
ddl.datesource=list<datasetvalues> // ...contains (colorcode, description)
ddl.DataTextField = "ColorCode";
ddl.DataValueField = "ColorCode";
ddl.databind();
then selected value should be like this...
ddlcolor.Items.FindByValue((DataBinder.Eval(formView1.DataItem,
"colorCode").ToString())).Selected = true;
for update:
ClassA.Color= ddl.selectedvalue();
Now what I need change to in the above code to get the combination of both..otherwise i need have textbox for description which syncs with ddl..which is bit complex for my level of programming...thanks..
There are a couple of solutions as per my knowlege.
1) You can concatenate the text like : Code + "-" + Value, while preparing the list using a For/Foreach... loop
2) If it is permitted as per your project, you may also consider overriding the string inside the entity but the selected value will be with a hyphenated(with a - inbetween code & value) string, which you need to string split in the code behind.
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
List<CodeValue> colors = new List<CodeValue> {new CodeValue{Code="",Value="Select"},new CodeValue{Code="RD",Value="Red"},
new CodeValue{Code="BL",Value="Blue"}};
ddlColors.DataSource = colors;
ddlColors.DataBind();
}
}
protected void btnClick_Click(object sender, EventArgs e)
{
var item = ddlColors.SelectedValue;
var code = item.Split('-');
}
}
class CodeValue
{
public string Code { get; set; }
public string Value { get; set; }
public override string ToString()
{
return this.Code + "-" + this.Value;
}
}

Categories

Resources