How to bind container of custom objects at design-time - c#

I want to have a container of objects that will be visualised in WinForms' DataGridView control.
As far as I know, I can bind a container to DataGridView via the DataSource property.
But I wonder, is there any way to do it in Designer? I see a lot of options related to that (like DataSource, DataMember etc) but I don't see any option that will give me a possibility to choose my own container inside the Form class.
I don't want to make this kind of stuff programmatically if it's available in the designer.

DataSource is bindable in designer. You can press the little arrow at the top of the DataGridView, and Choose Data Source. At the bottom> Add Project DataSource...
After adding the class, that will contain Your DataSource, You can set in the properties pane which public property is Your DataSource.
For example:
public class ThereIsDataSourceInThisClass
{
public ThereIsDataSourceInThisClass()
{
MyDataSource = new BindingList<Thing>();
MyDataSource.Add(new Thing { First = "aa", Second = "bb" });
}
public BindingList<Thing> MyDataSource { get; set; }
public class Thing
{
public string First { get; set; }
public string Second { get; set; }
}
}
I selected ThereIsDataSourceInThisClass in the wizard, than I selected MyDataSource in the DataSource property.
The result is>

Related

ObjectlistView Checkbox Issue

I have an issue trying to get a Checkbox working with ObjectListview.
My model looks like this:
public class object
{
public string name {get; set;}
public int age {get; set;}
public bool inuse {get; set;}
}
And I added a FastObjectListView via the Designer in Visual Studio to a Win Forms Application.
Then, I added the Columns and set the AspectName for each column to the Models Property (First column: AspectName: name, Second Column: AspectName: age, Third Column: AspectName: inuse).
Afterwards, I filled the ListView with this:
using (var context = new objectDb())
{
var objectlist = context.objects.ToList();
fastoLV_Clean.SetObjects(objectlist);
fastoLV_Clean.Refresh();
}
That works, and I can see my Database entries in the ListView.
Now I want to add a CheckBox column where someone can check or uncheck the items to delete them and I can not get the checkbox to work.
I have added a Column and set CheckBox to true, changed the CheckedAspectName of the ListView and now I can see the Checkboxes but nothing happens if I click them to check.
I think I'm on the completely wrong track, what do I have to do to make it work?
Thank you very much!!
I don't know a way with the ObjectListView to include any items which are not part of your model.
So then the simple way is to change your model to include a "Delete" property which you can then show in your ObjectListView.
Of course, this is not always possible! Especially if you are dealing with items that are written to/from Database or another persistence layer.
Then the trick is to write a derived class with you model being the base class and then you just add the delete column to this. But then you would need to convert from your Base to a derived class before showing in the ObjectListView.
The following code can help with that.
You keep your columns set-up as you have already done.
Assuming your (now base) class is defined like this
public class MyClass
{
public string name { get; set; }
public int age { get; set; }
public bool inuse { get; set; }
}
Your derived class inherits from this, adds the delete property and a new constructor
public class MySecondClass : MyClass
{
public bool Delete { get; set; }
public MySecondClass(MyClass other)
{
//Copy from MyClass
this.name = other.name;
this.age = other.age;
this.inuse = other.inuse;
//Set default for new properties
this.Delete = false;
}
}
Your code to retrieve the objects and set them then looks like this
using (var context = new objectDb())
{
var objectlist = context.objects.ToList();
//Now we need to convert to the derived class type
var secondlist = list.ConvertAll(x => new MySecondClass(x));
//Then we setobjects using this new list
fastoLV_Clean.SetObjects(secondlist);
}

Wpf DataGrid Set Columns dynamically by list property

I have a small caliburn micro MVVM project with a DataGrid. The columns will consist of x amount of 'setup's and the rows will consist of 'CustomRow'. I would like to use a ObservableCollection where CustomRow has a function property and a collection of setup property. For each setup in this collection a column should exist with the value of setup.
class CustomRow
{
public string Function { get; set; }
public ObservableCollection<Setup> Setups { get; set; }
}
// example class
class Setup
{
public string Name { get; set; }
public object Content { get; set; }
}
So I need to be able to add columns and rows dynamically depending on the itemssource (all the Setups collections will have the same size).
My problem is that I don't know how to translate the Setups property into multiple columns.
I have spend quit some time on what should be a mundane problem in my opinion. But I am missing something.
Any help is much appreciated.
Bind or set the ItemsSource to the ObservableCollection<CustomRow> and then get the Setups property of the first CustomRow in the source collection in the view, e.g.:
private void Window_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
var vm = DataContext as YourViewModel;
dataGrid.Columns.Clear();
if (vm.Rows != null && vm.Rows.Count > 0)
{
var setups = vm.Rows[0].Setups;
foreach (var setup in setups)
{
dataGrid.Columns.Add(new DataGridTextColumn { Header = setup.Name, Binding = new Binding("Content ") });
}
}
dataGrid.ItemsSource = vm.Rows;
}
There is no way to bind the Columns property of the DataGrid directly to a source property so you need to create the columns yourself one way or another.
You should do this in the view, in the control or in an attached behaviour that is attached to either of them. A view model should not create any columns.

Data Binding a List of Items and Selections

I am creating a WinForms application (for an instrumentation system) where the main form displays a list of equipment in a tableLayoutPanel wrapped in a groupBox. Each item has an associated label and comboBox. The application must populate the list of equipment at runtime, and then the user will select a value for each comboBox, which the application will fetch to run tests.
Here is a partial screenshot of what I'm describing:
I would like to make a class to hold the list of items, the possible options for the associated comboBox, and the user's selection and then data bind it such that changes to the class cause the correct controls to be created and populated. But I'm not sure if this is possible, and if it is, how I'd set up the binding sources?
Per this example, this is the class I think I should start with:
public class TestEquipment
{
public string Name { get; set; }
public List<string> Options { get; set; }
public string Selection { get; set; }
public TestEquipment(string name, string selection)
{
Name = name;
Selection = selection;
}
}

Create a simple DataGridView with List of objects and checkbox column (C#)

I have looked at a lot of places and I'm struggling to do this supposedly simple thing. I have a Windows form on which I've to show a simple DataGridView in this form:
| (CheckBoxColumn) | FilePath | FileState |
Now, there are a couple of problems. The data I need to bind to them is in a List of objects like this:
class FileObject
{
string filePath;
string fileState;
}
//Now here's the list of these objects which I populate somehow.
List<FileObject> listFiles;
Is there any efficient way to bind this directly to the DataGridView
so that different members of Object in the list are bound to
different columns, and for each there's checkbox?
I saw the examples of adding checkbox column to a datagrid, but none of them showed how
to add it to the 'header' row as well, so that it can behave as a 'check all'/'uncheck all' box.
Any help in how to achieve this would be great! I do write simple applications in C# but never had to work with datagrids etc. :(
Thanks!
The DataGridView control has a feature to automatically generate columns that can be set by the AutoGenerateColumns property. This property defaults to true - that is columns are by default auto generated.
However, columns are only automatically generated for public properties of the object you bind to the grid - fields do not show up.
Auto generation also works for check box columns when there is a public boolean property on the bound object.
So the simplest way to achieve your first two requirements is to change your FileObject class to this:
public class FileObject
{
public string FilePath { get; set; }
public string FileState { get; set; }
public bool Selected { get; set; }
}
If you cannot modify that class then next best would be the create a wrapper object that holds a file object:
public class FileObjectWrapper
{
private FileObject fileObject_;
FileObjectWrapper()
{
fileObject_ = new FileObject();
}
FileObjectWrapper(FileObject fo)
{
fileObject_ = fo;
}
public string FilePath
{
get { return fileObject_.filePath; }
set { fileObject_.filePath = value; }
}
public string FileState
{
get { return fileObject_.fileState; }
set { fileObject_.fileState= value; }
}
public bool Selected { get; set; }
}
You can then create your list to bind to (a BindingList is usually best) doing something like:
var fowList = new BindingList<FileObjectWrapper>();
foreach (FileObject fo in // here you have your list of file objects! )
{
fowList.Add(new FileObjectWrapper(fo));
}
dataGridView1.DataSource = fowList;
There are many ways to do the above but that is a general idea.
You can also add an unbound DataGridViewCheckBoxColumn to the grid, though I find it easier to have in the the bound list. Here is how if you do need to:
DataGridViewCheckBoxColumn c = new DataGridViewCheckBoxColumn();
c.Name = "Selected";
dataGridView1.Columns.Add(c);
Finally, for having a "SelectedAll" option in the header you will need to use custom code.
The article on CodeProject that Umesh linked to (CheckBox Header Column for DataGridView) looks quite easy to implement - they create a custom DataGridViewHeaderCell overriding the Paint and OnMouseClick methods.
Please refer the the below example, showing exactly what you are looking for
http://www.codeproject.com/Articles/20165/CheckBox-Header-Column-For-DataGridView

Set which property in POCO to display when databinding to drop down

If having a List filled with objects of the following type:
public class Person {
public string Name { get; set; }
public string Ssn { get; set; }
}
How can one set the value of the property Name to be what's beeing displayed within an ASP.NET DropDown, without setting any properties on the ASP.NET DropDown object? Of course, one way would be to ovveride ToString() on the class Person, but is there any other way to accomplish the same thing?
Thanx!
You can create new control derived from DropDown (e.g. DropDownEx), introduce new attributes e.g. DisplayFieldAttribute, ValueFieldAttribute. Then use TypeDescriptor.GetProperties to enumerate properties and analyze attributes for binding them respectively.

Categories

Resources