我是WPF / C#/ NET的新手,但我一直在学习编写一些小练习。
无论如何,我被困住了。我已经在这里和google上进行了搜索,无法找到答案,或者更准确地说找不到我能理解的答案。
我的问题是这个......使用Entity Framework我有两个表。一个用于员工详细信息,一个用于公司详细信息员工为0或1家公司工作。
我想通过WPF / XAML定义一个数据网格来导航Employees。但在每个员工行中,我想在没有相关公司记录的情况下显示他们所工作的公司的名称(如果有关系)或“失业”。
我没有提供表格的详细信息,因为它确实无关紧要 - 问题是在单个数据网格中显示来自父/子关系的连续信息。
我不知道这种问题的最佳方法是什么,我假设WPF / DataGrid,所以我真的很感谢如何去做,绑定(假设是WPF)甚至是一个例子WPF / XAML
提前致谢。
答案 0 :(得分:3)
有很多方法可以实现这一点 - 您可以尝试的一种方法是创建一个封装您想要显示的数据的视图模型 - 例如
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; } }
}
然后,给定IEnumerable<Employee>
,您可以将员工数据投影到此视图模型中,并将其设置为DataGrid的ItemsSource - 例如
IEnumerable<Employee> employees = GetEmployeesFromDatabase();
DataGrid1.ItemsSource = employees.Select(x => new EmployeeViewModel(x));
您通常会在此处通过xaml绑定设置ItemsSource,而不是直接在代码中设置它,但这将涉及使用设置为View的DataContext的父ViewModel,并且我试图保持简单。
使用DataGrid实现此目的的另一种方法是放弃使用视图模型,直接绑定到IEnumerable<Employee>
集合并明确设置列绑定 - 例如。
<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>
请注意,在第二个示例中,您不会在公司名称列中显示“失业”,其中没有关联公司的员工。
编辑:为了澄清关于从绑定到View的“主”视图模型上的属性设置Grid的项目源的观点,您可以创建一个表示整个当前视图的ViewModel类。 e.g。
public class MainViewModel
{
private readonly IEnumerable<Employee> _employees;
public MainViewModel(IEnumerable<Employee> employees)
{
_employees = employees;
}
public IEnumerable<Employee> Employees
{
get { return _employees; }
}
}
您将其设置为Window / UserControl的DataContext。
e.g。在简单的情况下,您可以在Window的构造函数中执行此操作(尽管在可能的情况下,对WPF应用程序的数据库调用实际上应该是异步的。)
public MainWindow()
{
InitializeComponent();
DataContext = new MainViewModel(GetAllEmployees());
}
然后你就可以在网格上设置绑定:
<DataGrid ItemsSource="{Binding Employees}" ...
然后,主窗口的数据上下文将用于其中包含的所有子控件,除非您在子控件上显式设置DataContext。在具有许多属性和命令的更复杂的ViewModel的情况下,此技术非常有用。如果您有兴趣了解更多信息,请查看MVVM模式以及Prism / Caliburn框架中的任何一个或两个。