WPF ComboBox selectedValue绑定失败 [英] WPF ComboBox selectedValue binding fails
问题描述
我有一个 ObservableCollection< Employee> ...
, ObservableCollection< Departments>
和 Enployee
定义为
public class Employee
{
[ Key]
public int Id {get;组; }
public string FirstName {get;组; }
public string LastName {get;组; }
public DateTime Birthday {get;组; }
public int DepId {get;组; }
[ForeignKey(DepId)]
public virtual Departments Departments {get;组; }
}
和部门
定义为
public class Departments
{
[Key]
public int Id {get;组; }
public string Name {get;组; }
public virtual IEnumerable< Employee>员工{get;组; }
}
在数据库中我有
看起来最后ComboBox无法找到属于相应Employee的DepId!
< DataGrid Name =DataGrid1Grid.Row =3Margin =10,0, 10,10
RenderOptions.ClearTypeHint =Enabled
TextOptions.TextFormattingMode =Display
CanUserAddRows =False
CanUserDeleteRows =False
SelectionUnit = FullRow
AutoGenerateColumns =false
SelectedItem ={Binding CurrentSelectedEmployee,Mode = TwoWay}
ItemsSource ={Binding Employees,Mode = TwoWay}>
< DataGrid.Columns>
<! - 第1列:员工ID - >
< DataGridTextColumn Header =Emplyee IdBinding ={Binding Id}/>
<! - 第2列:名字 - >
< DataGridTextColumn Header =First NameBinding ={Binding FirstName}/>
<! - 第3列:姓氏 - >
< DataGridTextColumn Header =Last NameBinding ={Binding LastName}/>
<! - 第4栏:出生日 - >
< DataGridTemplateColumn Header =Birth Day>
< DataGridTemplateColumn.CellTemplate>
< DataTemplate>
< DatePicker SelectedDate ={Binding Birthday}BorderThickness =0/>
< / DataTemplate>
< /DataGridTemplateColumn.CellTemplate>
< / DataGridTemplateColumn>
<! - 第5栏:部门ID - >
< DataGridTemplateColumn Header =Department>
< DataGridTemplateColumn.CellTemplate>
< DataTemplate>
< ComboBox ItemsSource ={Binding Departments}
DisplayMemberPath =NameSelectedValuePath =IdSelectedValue ={Binding DepId}/>
< / DataTemplate>
< /DataGridTemplateColumn.CellTemplate>
< / DataGridTemplateColumn>
< /DataGrid.Columns>
< / DataGrid>
看起来最后ComboBox找不到属于相应Employee的DepId! ?
UPDATE:My viewModel
public class MainViewModel:ViewModelBase
{
private readonly ManagerDbContext _context = new ManagerDbContext
public MainViewModel()
{
}
private IEnumerable< Departments> _departments;
public ObservableCollection< Departments> Departments
{
get
{
return
new ObservableCollection< Departments>(_ context.Departments);
}
set
{
_departments = value;
RaisePropertyChanged(Departments);
}
}
private IEnumerable< Employee> _雇员;
public IEnumerable< Employee> Employees
{
get
{
return
new ObservableCollection< Employee>(_ context.Employees.Include(e => e.Department));
}
set
{
_employee = value;
RaisePropertyChanged(Employees);
}
}
private Employee _currentSelectedEmployee;
public Employee CurrentSelectedEmployee
{
get
{
return _currentSelectedEmployee;
}
set
{
_currentSelectedEmployee = value;
RaisePropertyChanged(CurrentSelectedEmployee);
}
}
}
现在我看到了问题。当您使用ItemsSource时,ComboBox的每个项目都获得绑定到Department实体,而不是Employee。 Department实体是否具有属性DepId?可能不是,这是问题。如果你需要引用Employee,你需要这样做。
{Binding RelativeSource = {RelativeSource Mode = FindAncestor,AncestorType = { x:Type DataGrid}},Path = DepId}
Employee.Departments是什么?您确定它已初始化吗?
这对我有用:
{
public partial class MainWindow:Window
{
public ObservableCollection< Employee>员工{get;组; }
public MainWindow()
{
InitializeComponent();
Department dept1 = new Department(){Id = 1,Name =aaa};
Department dept2 = new Department(){Id = 2,Name =bbb};
Department dept3 = new Department(){Id = 3,Name =ccc};
ObservableCollection< Department> depts = new ObservableCollection< Department>();
depts.Add(dept1);
depts.Add(dept2);
depts.Add(dept3);
this.Employees = new ObservableCollection< Employee>();
this.Employees.Add(new Employee(){Id = 1,Birthday = DateTime.Now,FirstName =aaa,LastName =aaaa,DepId = 1,Departments = depts});
this.Employees.Add(new Employee(){Id = 2,Birthday = DateTime.Now,FirstName =aaa,LastName =bbbb,DepId = 2,Departments = depts}
this.Employees.Add(new Employee(){Id = 3,Birthday = DateTime.Now,FirstName =aaa,LastName =cccc,DepId = 3,Departments = depts}
this.Employees.Add(new Employee(){Id = 4,Birthday = DateTime.Now,FirstName =aaa,LastName =dddd,DepId = 2,Departments = depts}
this.DataContext = this;
}
}
}
public class Employee
{
public int Id {get;组; }
public string FirstName {get;组; }
public string LastName {get;组; }
public DateTime Birthday {get;组; }
public int DepId {get;组; }
public virtual ObservableCollection< Department>部门{get;组; }
}
public class Department
{
public int Id {get;组; }
public string Name {get;组; }
}
这是XAML:
< DataGrid Name =DataGrid1Grid.Row =3Margin =10,0,10,10
RenderOptions.ClearTypeHint =Enabled
TextOptions.TextFormattingMode =Display
CanUserAddRows =False
CanUserDeleteRows =False
SelectionUnit =FullRow
AutoGenerateColumns =false
SelectedItem ={Binding CurrentSelectedEmployee,Mode = TwoWay}
ItemsSource ={Binding Employees,Mode = TwoWay}>
< DataGrid.Columns>
<! - 第1列:员工ID - >
< DataGridTextColumn Header =Emplyee IdBinding ={Binding Id}/>
<! - 第2列:名字 - >
< DataGridTextColumn Header =First NameBinding ={Binding FirstName}/>
<! - 第3列:姓氏 - >
< DataGridTextColumn Header =Last NameBinding ={Binding LastName}/>
<! - 第4栏:出生日 - >
< DataGridTemplateColumn Header =Birth Day>
< DataGridTemplateColumn.CellTemplate>
< DataTemplate>
< DatePicker SelectedDate ={Binding Birthday}BorderThickness =0/>
< / DataTemplate>
< /DataGridTemplateColumn.CellTemplate>
< / DataGridTemplateColumn>
<! - 第5栏:部门ID - >
< DataGridTemplateColumn Header =Department>
< DataGridTemplateColumn.CellTemplate>
< DataTemplate>
< ComboBox ItemsSource ={Binding Departments}
DisplayMemberPath =NameSelectedValuePath =IdSelectedValue ={Binding DepId}/>
< / DataTemplate>
< /DataGridTemplateColumn.CellTemplate>
< / DataGridTemplateColumn>
< /DataGrid.Columns>
< / DataGrid>
I have an
ObservableCollection<Employee>...
, anObservableCollection<Departments>
andEnployee
is defined aspublic class Employee { [Key] public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public DateTime Birthday { get; set; } public int DepId { get; set; } [ForeignKey("DepId")] public virtual Departments Departments { get; set; } }
and
Department
is defined aspublic class Departments { [Key] public int Id { get; set; } public string Name { get; set; } public virtual IEnumerable<Employee> Employees { get; set; } }
In the database I have
It looks like last ComboBox fails to locate the DepId which belongs to the corresponding Employee!! Any ideas guys?
<DataGrid Name="DataGrid1" Grid.Row="3" Margin="10,0,10,10" RenderOptions.ClearTypeHint="Enabled" TextOptions.TextFormattingMode="Display" CanUserAddRows="False" CanUserDeleteRows="False" SelectionUnit="FullRow" AutoGenerateColumns="false" SelectedItem="{Binding CurrentSelectedEmployee, Mode=TwoWay}" ItemsSource="{Binding Employees, Mode=TwoWay}"> <DataGrid.Columns> <!--Column 1: Employee Id--> <DataGridTextColumn Header="Emplyee Id" Binding="{Binding Id}"/> <!--Column 2: First Name--> <DataGridTextColumn Header="First Name" Binding="{Binding FirstName}"/> <!--Column 3: Last Name--> <DataGridTextColumn Header="Last Name" Binding="{Binding LastName}"/> <!--Column 4: Birth Day--> <DataGridTemplateColumn Header="Birth Day" > <DataGridTemplateColumn.CellTemplate> <DataTemplate> <DatePicker SelectedDate="{Binding Birthday}" BorderThickness="0" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <!--Column 5: Department Id--> <DataGridTemplateColumn Header="Department" > <DataGridTemplateColumn.CellTemplate> <DataTemplate> <ComboBox ItemsSource="{Binding Departments}" DisplayMemberPath="Name" SelectedValuePath="Id" SelectedValue="{Binding DepId}" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid>
It looks like last ComboBox fails to locate the DepId which belongs to the corresponding Employee!! Any ideas guys?
UPDATE: My viewModel
public class MainViewModel : ViewModelBase { private readonly ManagerDbContext _context = new ManagerDbContext(); public MainViewModel() { } private IEnumerable<Departments> _departments; public ObservableCollection<Departments> Departments { get { return new ObservableCollection<Departments>(_context.Departments); } set { _departments = value; RaisePropertyChanged("Departments"); } } private IEnumerable<Employee> _employee; public IEnumerable<Employee> Employees { get { return new ObservableCollection<Employee>(_context.Employees.Include(e => e.Department)); } set { _employee = value; RaisePropertyChanged("Employees"); } } private Employee _currentSelectedEmployee; public Employee CurrentSelectedEmployee { get { return _currentSelectedEmployee; } set { _currentSelectedEmployee = value; RaisePropertyChanged("CurrentSelectedEmployee"); } } }
解决方案now I see the problem. When you use the ItemsSource, then each item of ComboBox gets the binding to Department entity, not to Employee. Does Department entity has a property DepId? Probably not, and that's is the problem. If you need to refer to Employee you need to do this.
{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}, Path=DepId}
Employee.Departments what is this? Are you sure it's initialized?
This is what works for me:
{ public partial class MainWindow : Window { public ObservableCollection<Employee> Employees { get; set; } public MainWindow() { InitializeComponent(); Department dept1 = new Department() { Id = 1, Name = "aaa" }; Department dept2 = new Department() { Id = 2, Name = "bbb" }; Department dept3 = new Department() { Id = 3, Name = "ccc" }; ObservableCollection<Department> depts = new ObservableCollection<Department>(); depts.Add(dept1); depts.Add(dept2); depts.Add(dept3); this.Employees = new ObservableCollection<Employee>(); this.Employees.Add(new Employee() { Id = 1, Birthday = DateTime.Now, FirstName = "aaa", LastName = " aaaa", DepId = 1, Departments = depts }); this.Employees.Add(new Employee() { Id = 2, Birthday = DateTime.Now, FirstName = "aaa", LastName = " bbbb", DepId = 2, Departments = depts }); this.Employees.Add(new Employee() { Id = 3, Birthday = DateTime.Now, FirstName = "aaa", LastName = " cccc", DepId = 3, Departments = depts }); this.Employees.Add(new Employee() { Id = 4, Birthday = DateTime.Now, FirstName = "aaa", LastName = " dddd", DepId = 2, Departments = depts }); this.DataContext = this; } } } public class Employee { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public DateTime Birthday { get; set; } public int DepId { get; set; } public virtual ObservableCollection<Department> Departments { get; set; } } public class Department { public int Id { get; set; } public string Name { get; set; } }
and this is XAML:
<DataGrid Name="DataGrid1" Grid.Row="3" Margin="10,0,10,10" RenderOptions.ClearTypeHint="Enabled" TextOptions.TextFormattingMode="Display" CanUserAddRows="False" CanUserDeleteRows="False" SelectionUnit="FullRow" AutoGenerateColumns="false" SelectedItem="{Binding CurrentSelectedEmployee, Mode=TwoWay}" ItemsSource="{Binding Employees, Mode=TwoWay}"> <DataGrid.Columns> <!--Column 1: Employee Id--> <DataGridTextColumn Header="Emplyee Id" Binding="{Binding Id}"/> <!--Column 2: First Name--> <DataGridTextColumn Header="First Name" Binding="{Binding FirstName}"/> <!--Column 3: Last Name--> <DataGridTextColumn Header="Last Name" Binding="{Binding LastName}"/> <!--Column 4: Birth Day--> <DataGridTemplateColumn Header="Birth Day" > <DataGridTemplateColumn.CellTemplate> <DataTemplate> <DatePicker SelectedDate="{Binding Birthday}" BorderThickness="0" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <!--Column 5: Department Id--> <DataGridTemplateColumn Header="Department" > <DataGridTemplateColumn.CellTemplate> <DataTemplate> <ComboBox ItemsSource="{Binding Departments}" DisplayMemberPath="Name" SelectedValuePath="Id" SelectedValue="{Binding DepId}" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid>
这篇关于WPF ComboBox selectedValue绑定失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!