I have a StringCollection that I want to One Way Bind to a ListView. As in, the ListView should display the contents of the StringCollection. I will be removing items from the collection programatically so they don't need to interact with it through the ListView.
I have a Form with a Property, like so -->
public DRIUploadForm()
{
InitializeComponent();
lvwDRIClients.DataBindings.Add("Items", this.DirtyDRIClients, "DirtyDRIClients");
}
private StringCollection _DirtyDRIClients;
public StringCollection DirtyDRIClients
{
get
{
return _DirtyDRIClients;
}
set
{
_DirtyDRIClients = Settings.Default.DRIUpdates;
}
}
You cannot actually bind to a ListView control, as it does not support binding. You need to add the items programmatically. You can however bind to a ListBox, although as others have said you cannot bind strings directly, you need to create a wrapper for them. Something like this...
public partial class Form1 : Form
{
List<Item> items = new List<Item>
{
new Item { Value = "One" },
new Item { Value = "Two" },
new Item { Value = "Three" },
};
public Form1()
{
InitializeComponent();
listBox1.DataSource = items;
listBox1.DisplayMember = "Value";
}
}
public class Item
{
public string Value { get; set; }
}
Related
I'm using PRISM6.
In my Model I have simple:
public ObservableCollection<Id> Ids { get; }
In ViewModel I would like to return those items in public ObservableCollection<string> Ids
How can I convert it to string? At this moment I have:
private ObservableCollection<string> _ids = new ObservableCollection<string>();
public ObservableCollection<string> Ids {
get {
_ids.Add("Empty");
foreach (var item in _Model.Ids) {
_ids.Add(item.ToString());
}
return _ids;
}
}
But it does not work when I update my collection in Model.
My old version without convert works fine. public ObservableCollection<Id> Ids => _Model.Ids; I need it in string because somehow I need to add "Empty" to combobox. If ther is any better solution for it please tell me :)
I'm sure there are much better solutions out there, but here's one method I particularly like:
public class MainViewModel
{
// Source Id collection
public ObservableCollection<Id> Ids { get; }
// Empty Id collection
public ObservableCollection<Id> Empty { get; } = new ObservableCollection<Id>();
// Composite (combination of Source + Empty collection)
// View should bind to this instead of Ids
public CompositeCollection ViewIds { get; }
// Constructor
public MainViewModel(ObservableCollection<Id> ids)
{
ViewIds = new CompositeCollection();
ViewIds.Add(new CollectionContainer {Collection = Empty });
ViewIds.Add(new CollectionContainer {Collection = Ids = ids });
// Whenever something changes in Ids, Update the collections
CollectionChangedEventManager.AddHandler(Ids, delegate { UpdateEmptyCollection(); });
UpdateEmptyCollection(); // First time
}
private void UpdateEmptyCollection()
{
// If the source collection is empty, push an "Empty" id into the Empty colleciton
if (Ids.Count == 0)
Empty.Add(new Id("Empty"));
// Otherwise (has Ids), clear the Empty collection
else
Empty.Clear();
}
}
I have a DataGrid in my View as shown below.,
My Question is how can I Append the values from the textboxes to the row datagrid
I have make sure that the Model has All the properties, When I click on the Add button it overwrites the dataGrid and shows only one latest record the and my ViewModel look like this:
class BatchItemsViewModel : ViewModelBase
{
public SearchItemsModel msearchItems { get; set; }
ObservableCollection<SearchItemsModel> _BatchItemsGrid;
public ObservableCollection<SearchItemsModel> BatchItemsGrid
{
get { return _BatchItemsGrid; }
set
{
_BatchItemsGrid = value;
OnPropertyChanged("BatchItemsGrid");
}
}
private ICommand _addDataToBatchGrid;
public ICommand addDataToBatchGrid
{
get
{
return _addDataToBatchGrid;
}
set
{
_addDataToBatchGrid = value;
}
}
public BatchItemsViewModel()
{
msearchItems = new SearchItemsModel();
addDataToBatchGrid = new RelayCommand(new Action<object>(AddDataInBatchGrid));
}
public void AddDataInBatchGrid(object obj)
{
ObservableCollection<SearchItemsModel> batchGridData = new ObservableCollection<SearchItemsModel>();
var data = new SearchItemsModel
{
BatchNumber = msearchItems.BatchNumber,
MFDDate = msearchItems.MFDDate,
ExpiryDate = msearchItems.ExpiryDate,
Quantity = msearchItems.Quantity,
};
batchGridData.Add(data);
BatchItemsGrid = batchGridData; // HERE I am overwriting the datagrid
//How can I Append the batchGridData to BatchItemsGrid (BatchItemsGrid.Append(batchGridData)???)
}
}
NOTE: I have gone through the other threads as well in the community for the similar posts but I couldn't find the appropriate and please correct me if I am going in wrong direction.
public void AddDataInBatchGrid(object obj)
{
var data = new SearchItemsModel
{
BatchNumber = msearchItems.BatchNumber,
MFDDate = msearchItems.MFDDate,
ExpiryDate = msearchItems.ExpiryDate,
Quantity = msearchItems.Quantity,
};
this.BatchItemsGrid.Add(data);
}
...Should do the trick. (don't replace the whole collection, just add items to it and let the notification events handle the UI updates)
Sorry for my bad English :(.
Hi, how do I add the items to a ListView that I've put in a List?
I've tried this:
listView1.Items.Add(pluginContainer);
But this doesn't seem to work :(.
I can't make a foreach loop because then it will take like 10 seconds for the ListView to be filled (I'm talking about 5000+ items).
This fixed it:
listView1.Items.AddRange(pluginContainer.ToArray());
If the items in your list are all of type ListViewItem, you can use AddRange. If they're not, you're going to have to either make ListViewItems out of them, or use a for loop.
In either case, you should strive to improve the performance of a ListView during addition of items, by first calling SuspendLayout on it. After you've added all its items, call ResumeLayout.
Try this:
public enum State
{
AL, GA, FL, SC, TN, MI
}
public class Person
{
public int ID { get; set; }
public string Name { get; set; }
public State State { get; set; }
// Converts properties to string array
public string[] ToListViewItem()
{
return new string[] {
ID.ToString("00000"),
Name,
State.ToString() };
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//Setup list view column headings and widths
listView1.Columns.Add("ID", 48);
listView1.Columns.Add("Name", 300);
listView1.Columns.Add("State", 48);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
// Create a list
List<Person> list = new List<Person>();
// Fill in some data
list.Add(new Person() { ID=1001, Name="John", State=State.TN });
list.Add(new Person() { ID=1002, Name="Roger", State=State.AL });
list.Add(new Person() { ID=1003, Name="Samantha", State=State.FL});
list.Add(new Person() { ID=1004, Name="Kara", State=State.MI});
// Fill in ListView from list
PopulateListView(list);
}
void PopulateListView(List<Person> list)
{
listView1.SuspendLayout();
for(int i=0; i<list.Count; i++)
{
// create a list view item
var lvi = new ListViewItem(list[i].ToListViewItem());
// assign class reference to lvi Tag for later use
lvi.Tag = list[i];
// add to list view
listView1.Items.Add(lvi);
}
//This adjust the width of 1st column to fit data.
listView1.AutoResizeColumn(0, ColumnHeaderAutoResizeStyle.ColumnContent);
listView1.ResumeLayout();
}
}
I have a table that have these fields: ID , Name
I have bound a listbox to the table.
My question is, when the user has selected an item in listbox, how would I find out what the ID of the selected item is?
Note: The id is not equal to the selectedindex or id of items in items list
e.g.
Suppose you have a DataTable dt, with columns ID and Name in it.
then while binding include the following code,
this.listbox.DataSource = dt;
this.listbox.DisplayMember = "Name";
this.listbox.ValueMember = "ID";
while reading the selected values of listbox,
this.listbox.SelectedItem will give u the selected Name and
this.listbox.SelectedValue will give u the corresponding ID
test it
lst.SelectedItem.Value;
OR
lst.SelectedValue;
where lst is a ListBox Cotrol
What type of application is this? ASP.net, Windows Forms, WPF?
I have a feeling you are working with Windows Forms, as the other two are much clearer...
Here is some code for a Windows Forms App... Basically, you create your own class, and use that for the list items. The list box will display the results of the ToString() method, so override that to get the value you wanna display. When you access ListBox.SelectedItem, it will be an instance of the class you defined, and you can access whatever properties are necessary:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
MyListItem item1 = new MyListItem("Java", 1);
MyListItem item2 = new MyListItem("C#", 221);
MyListItem item3 = new MyListItem("C++", 13);
listBox1.Items.Add(item1);
listBox1.Items.Add(item2);
listBox1.Items.Add(item3);
}
private class MyListItem
{
public string ItemName { get; set; }
public int ItemId { get; set; }
public MyListItem(string name, int id)
{
this.ItemName = name;
this.ItemId = id;
}
public override string ToString()
{
return this.ItemName;
}
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
MyListItem selectedItem = (MyListItem)listBox1.SelectedItem;
MessageBox.Show(string.Format("Name is: {0}, Id is: {1}", selectedItem.ItemName, selectedItem.ItemId));
}
}
Could any body give a short example for binding a value from list array to listbox in c#.net
It depends on how your list array is.
Let's start from an easy sample:
List<string> listToBind = new List<string> { "AA", "BB", "CC" };
this.listBox1.DataSource = listToBind;
Here we have a list of strings, that will be shown as items in the listbox.
Otherwise, if your list items are more complex (e.g. custom classes) you can do in this way:
Having for example, MyClass defined as follows:
public class MyClass
{
public int Id { get; set; }
public string Text { get; set; }
public MyClass(int id, string text)
{
this.Id = id;
this.Text = text;
}
}
here's the binding part:
List<MyClass> listToBind = new List<MyClass> { new MyClass(1, "One"), new MyClass(2, "Two") };
this.listBox1.DisplayMember = "Text";
this.listBox1.ValueMember = "Id"; // optional depending on your needs
this.listBox1.DataSource = listToBind;
And you will get a list box showing only the text of your items.
Setting also ValueMember to a specific Property of your class will make listBox1.SelectedValue containing the selected Id value instead of the whole class instance.
N.B.
Letting DisplayMember unset, you will get the ToString() result of your list entries as display text of your ListBox items.