您好我实际上正在创建一个WPF DataGrid自定义控件。 想要的是这个组合框应该显示组合框中的性别以及当我将组合框保持在数据模板外时它的工作状态,但是在数据模板内它不能正常工作。请帮帮我?
<UserControl x:Class="Custom_DataGrid.Grid3.Grid3"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" xmlns:sdk="http://schemas.microsoft.com/wpf/2008/toolkit"
d:DesignHeight="300" d:DesignWidth="300" >
<UserControl.Resources>
<DataTemplate x:Key="dueDateCellTemplate">
<TextBlock Text="{Binding DOB}" Margin="5,4,5,4"/>
</DataTemplate>
<DataTemplate x:Key="dueDateCellEditingTemplate">
<DatePicker SelectedDate="{Binding DOB, Mode=TwoWay}"/>
</DataTemplate>
<DataTemplate x:Key="genderCellTemplate">
<TextBlock Text="{Binding GENDER.Gender}" Margin="5,4,5,4"/>
</DataTemplate>
<DataTemplate x:Key="genderCellEditingTemplate">
<!--<ComboBox ItemsSource="{Binding Genders}" SelectedItem="{Binding Genders}" SelectedValue="{Binding Path=GENDER, ElementName=Id}" DisplayMemberPath="Id" SelectedValuePath="Gender"></ComboBox>-->
<ComboBox x:Name="c1" ItemsSource="{Binding Genders}" DisplayMemberPath="Id" Height="50" Width="100"></ComboBox>
<!--<TextBlock Text="{Binding Genders.Gender}" Foreground="Khaki"></TextBlock>-->
</DataTemplate>
</UserControl.Resources>
<Grid>
<DataGrid x:Name="datagrid3" AutoGeneratingColumn="datagrid3_AutoGeneratingColumn" ItemsSource="{Binding Employees}" Foreground="SteelBlue"></DataGrid>
</Grid>
</UserControl>
public enum Designation
{
Sales, Development, HR, BackOffice
}
public class Sex
{
private string id;
private string gen;
public string Id
{
get
{
return id;
}
set
{
id = value;
}
}
public string Gender
{
get
{
return gen;
}
set
{
gen = value;
}
}
}
public class DataSource
{
ObservableCollection<Employee> empList = new ObservableCollection<Employee>();
List<Sex> genders = new List<Sex>();
public DataSource()
{
empList.Add(new Employee() { ID = 1, NAME = "Neeraj", DOB = Convert.ToDateTime("12/03/1986"), EMAIL = "neeraj@mail.com", GENDER = new Sex() { Id = "M", Gender = "Male" }, PHONE = "9999999999", ACTIVE = false, DESIGNATION = Designation.Development });
empList.Add(new Employee() { ID = 2, NAME = "Mayank", DOB = Convert.ToDateTime("01/01/1986"), EMAIL = "mayank@mail.com", GENDER = new Sex() { Id = "M", Gender = "Male" }, PHONE = "9999999999", ACTIVE = true, DESIGNATION = Designation.BackOffice });
empList.Add(new Employee() { ID = 1, NAME = "Neeraj", DOB = Convert.ToDateTime("12/03/1986"), EMAIL = "neeraj@mail.com", GENDER = new Sex() { Id = "M", Gender = "Male" }, PHONE = "9999999999", ACTIVE = false, DESIGNATION = Designation.Development });
empList.Add(new Employee() { ID = 2, NAME = "Mayank", DOB = Convert.ToDateTime("01/01/1986"), EMAIL = "mayank@mail.com", GENDER = new Sex() { Id = "M", Gender = "Male" }, PHONE = "9999999999", ACTIVE = true, DESIGNATION = Designation.BackOffice });
empList.Add(new Employee() { ID = 1, NAME = "Neeraj", DOB = Convert.ToDateTime("12/03/1986"), EMAIL = "neeraj@mail.com", GENDER = new Sex() { Id = "M", Gender = "Male" }, PHONE = "9999999999", ACTIVE = false, DESIGNATION = Designation.Development });
empList.Add(new Employee() { ID = 2, NAME = "Mayank", DOB = Convert.ToDateTime("01/01/1986"), EMAIL = "mayank@mail.com", GENDER = new Sex() { Id = "M", Gender = "Male" }, PHONE = "9999999999", ACTIVE = true, DESIGNATION = Designation.BackOffice });
genders.Add(new Sex() { Id = "M", Gender = "Male" });
genders.Add(new Sex() { Id = "F", Gender = "Female" });
}
public ObservableCollection<Employee> Employees
{
get
{
return empList;
}
set
{
empList = value;
}
}
public List<Sex> Genders
{
get
{
return genders;
}
set
{
genders = value;
}
}
}
编码xaml.cs文件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Custom_DataGrid.Grid3
{
/// <summary>
/// Interaction logic for Grid3.xaml
/// </summary>
public partial class Grid3 : UserControl
{
public Grid3()
{
InitializeComponent();
this.DataContext = new DataSource();
}
private void datagrid3_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
if (e.PropertyName.ToLower().ToString().Equals("id"))
{
e.Column.Header = "Employee Id";
}
else if (e.PropertyName.ToLower().Equals("name"))
{
e.Column.Header = "Employee Name";
}
else if (e.PropertyName.ToLower().Equals("dob"))
{
e.Column.Header = "Employee DOB";
if (e.PropertyType == typeof(DateTime))
{
DataGridTemplateColumn templateColumn = new DataGridTemplateColumn();
templateColumn.Header = "Employee DOB";
templateColumn.CellTemplate = (DataTemplate)Resources["dueDateCellTemplate"];
templateColumn.CellEditingTemplate = (DataTemplate)Resources["dueDateCellEditingTemplate"];
templateColumn.SortMemberPath = "DueDate";
e.Column = templateColumn;
}
}
else if (e.PropertyName.ToLower().Equals("phone"))
{
e.Column.Header = "Employee Phone";
e.Cancel = true;
}
else if (e.PropertyName.ToLower().Equals("email"))
{
e.Column.Header = "Employee Email";
}
else if (e.PropertyName.ToLower().Equals("gender"))
{
e.Column.Header = "Employee Gender";
DataGridTemplateColumn templateColumn = new DataGridTemplateColumn();
templateColumn.Header = "Employee Gender";
templateColumn.CellTemplate = (DataTemplate)Resources["genderCellTemplate"];
templateColumn.CellEditingTemplate = (DataTemplate)Resources["genderCellEditingTemplate"];
e.Column = templateColumn;
}
else if (e.PropertyName.ToLower().Equals("active"))
{
e.Column.Header = "Employee Active/InActive";
}
else if (e.PropertyName.ToLower().Equals("designation"))
{
e.Column.Header = "Employee Designation";
}
}
}
}
所以我试图在celleditingtemplate中使用combobxo创建模板列,每个东西都工作正常,但在datatemplate内部它不起作用。 请帮我?检查我评论过的文本框是否正常工作......
答案 0 :(得分:3)
如果您在DataTemplate中,DataContext将是模板化的对象。因此,如果只指定了绑定路径,那么相对于DataContext的绑定将找不到ItemsSource。
通常,您可以使用RelativeSource
- 绑定来查找仍具有可以找到ItemsSource的DataContext的控件。 (请参阅RV1987的答案;我认为它之前没有用,因为如果你有一个DataGridComboBoxColumn
相同的RelativeSource-ItemsSource-binding将不能工作,那是因为它本身是抽象的,不会出现在树中,而不像模板创建的控件)
由于UserControl的DataContext应该是你要找的东西,你可以命名你的UserControl(例如control
)并像这样绑定:
ItemsSource="{Binding Source={x:Reference control}, Path=DataContext.Genders}"
(请注意x:Reference
是新的,它在.NET 3.5中不存在,使用ElementName=control
而不是不工作)
答案 1 :(得分:0)
尝试在datatemplate中使用它 -
<ComboBox x:Name="c1" ItemsSource="{Binding DataContext.Genders, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" DisplayMemberPath="Id" Height="50" Width="100"></ComboBox>
这将在您的usercontrol的datacontext中找到属性Genders,它是DataSource。