WPF DataGrid Parent Child Data
I'm new to WPF/C#/NET but I have been learning by way of coding some small exercises.
Any开发者_运维知识库way, I'm stuck. I have seached on here and google and can't find the answer or maybe more correctly can't find an answer I can make sense of.
My problem is this... using the Entity Framework I have two tables. One for Employee details and one for Company details. Employees work for 0 or 1 Company's.
I would like to, via WPF/XAML, define a datagrid to navigate Employees. But within each employee row I would like to show the name of the Company they work for (if there is a relationship) or "Unemployed" in the cases where there is no related Company record.
I have not given details of the tables as it really doesnt matter - the problem is displaying concatentated information from parent/child relationships in a single datagrid.
I dont know what the best approach to this kind of problem is, I'm assuming WPF/DataGrid, so I would really appreciate help on how to go about doing it, the binding (assuming WPF) or even an example of the WPF/XAML
Thanks in advance.
There are many ways to accomplish this - one way you might try is to create a View Model that encapsulates the data you want to display - e.g.
public class EmployeeViewModel
{
private readonly Employee _employee;
public EmployeeViewModel(Employee employee)
{
_employee = employee;
}
public string Name { get { return _employee.Name; } }
public string CompanyName { get { return _employee.Company == null ? "Unemployed" : _employee.Company.CompanyName; } }
}
Then, given an IEnumerable<Employee>
you can project your employee data into this view model and set it as the ItemsSource of your DataGrid - e.g.
IEnumerable<Employee> employees = GetEmployeesFromDatabase();
DataGrid1.ItemsSource = employees.Select(x => new EmployeeViewModel(x));
You would normally set the ItemsSource via a xaml binding here rather than setting it directly in code but that would involve the use of a parent ViewModel set as the DataContext of the View and I'm trying to keep things simple.
Another way to accomplish this with a DataGrid would be to forgo the use of a View Model, bind directly to an IEnumerable<Employee>
collection and set the column bindings explicitly - e.g.
<DataGrid ItemsSource="{Binding Employees}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Employee Name" Binding="{Binding Name}" />
<DataGridTextColumn Header="Company Name" Binding="{Binding Company.Name}" />
</DataGrid.Columns>
</DataGrid>
Note that with the second example, you won't get "Unemployed" appearing in the Company Name column where there is no associated company for an employee.
EDIT: To clarify the point about setting the items source for your Grid from a property on a 'main' view model bound to the View, you might create a ViewModel class that represents the whole of the current view. e.g.
public class MainViewModel
{
private readonly IEnumerable<Employee> _employees;
public MainViewModel(IEnumerable<Employee> employees)
{
_employees = employees;
}
public IEnumerable<Employee> Employees
{
get { return _employees; }
}
}
You'd set this as the DataContext for the Window / UserControl.
e.g. in simple cases you could do this in the constructor for your Window (although calls to the database should really be asynchronous for WPF apps where possible).
public MainWindow()
{
InitializeComponent();
DataContext = new MainViewModel(GetAllEmployees());
}
Then you can set up the binding on your Grid like this:
<DataGrid ItemsSource="{Binding Employees}" ...
The data context for the main window is then used for all the child controls contained therein except where you explicitly set the DataContext on a child control. This technique becomes useful where you have more complex ViewModels with many properties and commands. If you are interested in finding out more you should take a look at the MVVM pattern and either or both of the Prism / Caliburn frameworks.
精彩评论