2

I have employee class, which has field of type ISalary (Interface). In data grid view, I want to display that salary, but what I get is empty field. Is it any possible way to display that "custom type field" in data grid view? invoking toString method would help, but I can't understand how to do that. Here is how I am binding data:

 employeeBindingSource.DataSource = employeesList;

All fields in that list, ofc is not null. And here is some of my class, which list I want to display:

 public class Employee
 {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Gender { get; set; }
        public int DepartmentId { get; set; }

        // how to display this?
        public ISalary Salary { get; set; }

        ...
 }

I did some research and could not find any example on it. Or maybe was not trying hard enough.:/

Unknown
  • 108
  • 9
  • 1
    Take a look at this post: [How to bind a column from second level list on bindsource in winforms datagridview](https://stackoverflow.com/questions/36469904/how-to-bind-a-column-from-second-level-list-on-bindsource-in-winforms-datagridvi) or this one: [Show Properties of a Navigation Property in DataGridView (Second Level Properties)](https://stackoverflow.com/questions/35088181/show-properties-of-a-navigation-property-in-datagridview-second-level-propertie), In this case which you are using the interface `ISalary`, the best option is using `CellFormatting` or using a `ComboBox` column. – Reza Aghaei Nov 21 '16 at 21:01
  • 1
    If you want to follow overriding `ToString`, you should know what is the implemented type of `ISalary` which is in `Salary` property and override `ToString` method of that type, but it's not a good idea because it's like you use that type instead of the interface and your application will loose it's goal from using the `ISalary` interface. – Reza Aghaei Nov 21 '16 at 21:11
  • @RezaAghaei I am just wondering, why is it not possible to override ToString without knowing concrete implementation type? I mean it should work.. Yes, It will not give correct result if ToString method is not overriden, but still.. – Unknown Nov 21 '16 at 21:27
  • 1
    An interface can not contain implementation. The implementation belongs to classes and if you know the concrete type, you can override the implementation. Also you can use an abstract type instead of the interface, then the abstract class can override implementation of the `ToString`. You also can add a readonly property to the `Employee` class which returns a known string property of salary like this: `this.Salary.Something`. I believe you will find useful options in the linked posts :) – Reza Aghaei Nov 21 '16 at 21:32
  • I posted an answer as conclusion :) – Reza Aghaei Nov 21 '16 at 21:53

3 Answers3

2

Since you are using a interface as type of property, you can not override ToString method for that ISalary type without knowing the concrete type. So if you know a Salary class which implemented that interface and used instead of that interface at run-time, you can override ToString of that type.

But, in general it's not a good idea to rely on ToString of that concrete type, this way your program will be tightly relied on the concrete type and will loose its goal in using the interface.

Instead, you can use either of these options:

  • Use CellFormatting event to provide display value.
  • Use a DataGridViewComboBoxColumn which contains a List<Salary> but, set its display style property to nothing to not show dropdown button.
  • Use a readonly property in Employee class which return a known property of ISalary, like return this.Salary.SomeProperty;

And still there are more options. To see some other options and examples, take a look at this post: How to bind a column from second level list on bindsource in winforms datagridview or this one: Show Properties of a Navigation Property in DataGridView (Second Level Properties).

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
0

This should work for you:

public ISalary Salary 
{ 
get{ return this.Salary.ToString(); }; 
set; 
}

To use ToString(), you only append it at the end of the object you want to be returned as a string.

See the official MSDN on the ToString() function:

Object.ToString Method

Dart Feld
  • 213
  • 4
  • 18
  • Well it is not so easy probably. I tried it and got "cannot implicitly convert string to ISalary", because returning type should match I guess. Resharper offers only one solution: change type of property to string.. – Unknown Nov 21 '16 at 21:01
  • May be you can also override ToString in the class that implements ISalary to get your custom view – Yaman Nov 21 '16 at 21:01
0
interface ISalary
{
    public decimal Amount { get; set; }
    public string GetSalaryString();
}

the code:

List<Employee> lstEmployee = GetEmployeeList();
dataGridView1.Rows.Clear();

if (lstEmployee.Count == 0)
    return;

foreach (var employee in lstEmployee)
{
    DataGridViewRow dgvr = dataGridView1.Rows[dataGridView1.Rows.Add()];
    dgvr.Cells[colnId.Index].Value = employee.Id;
    dgvr.Cells[colnName.Index].Value = employee.Name;
    dgvr.Cells[colnGender.Index].Value = employee.Gender;
    dgvr.Cells[colnDepartmentId.Index].Value = employee.DepartmentId;
    dgvr.Cells[colnSalary.Index].Value = employee.Salary.GetSalaryString();
}
mjb
  • 7,649
  • 8
  • 44
  • 60
  • Well in this case you have to add everything programmatically, columns included, and dont have any bound source. But, anyway, thank you for alternative solution. – Unknown Nov 22 '16 at 08:34