为什么我必须在WPF中使用DataGrid在具有Content属性的对象之间使用类型转换?

lkaoscv7  于 2022-11-26  发布在  其他
关注(0)|答案(1)|浏览(148)

我使用Entity Framework和MSSQL创建了一个WPF项目。
问题是,当我想显示id的内容时,我必须将其类型转换为TextBlock,否则,我会收到一条错误消息,我不知道原因是什么,为什么我必须这样做。
这就是我说的台词:lblID.Content = ((TextBlock)id.Content).Text;
我为什么不能直接写:lblID.Content = id.Content;使用以下代码,当我加载DataGrid并选择一行时,第一列的id值消失,当最后一列的id值也消失时,将弹出一个NullReferenceException

下面是我的全部代码:

public partial class MainWindow : Window
    {
        hospitalEntities hp = new hospitalEntities();
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            InitializeTable();
        }

        private void InitializeTable()
        {
            dgPatientTable.ItemsSource = null;
            var query = from patient in hp.patients
                        select
                        new
                        {
                            patient.ID,
                            patient.name,
                            patient.phone,
                            patient.email,
                            patient.address,
                            patient.postalZip
                        };
            dgPatientTable.ItemsSource = query.ToList();
        }

        private void btnAddPatient_Click(object sender, RoutedEventArgs e)
        {
            using (hp)
            {
                patient Patient = new patient()
                {
                    name = tbName.Text,
                    phone = tbPhone.Text,
                    email = tbEmail.Text,
                    address = tbAddress.Text,
                    postalZip = tbPostalZip.Text
                };
                hp.patients.Add(Patient);
                hp.SaveChanges();
                tbName.Text = "";
                tbPhone.Text = "";
                tbEmail.Text = "";
                tbAddress.Text = "";
                tbPostalZip.Text = "";
                InitializeTable();
            }
        }

        int patientId = 0;
        private void dgPatientTable_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            DataGrid dataGrid = sender as DataGrid;
            DataGridRow row = (DataGridRow)dataGrid.ItemContainerGenerator
                                .ContainerFromIndex(dataGrid.SelectedIndex);
            DataGridCell id;
            try
            {
                id = (DataGridCell)dataGrid.Columns[0].GetCellContent(row).Parent;
            }
            catch
            {
                return;
            }

            lblID.Content = ((TextBlock)id.Content).Text;

            try
            {
                patientId = int.Parse(((TextBlock)id.Content).Text);
            }
            catch
            {
                patientId = 0;
                return;
            }
            DataGridCell name = (DataGridCell)dataGrid.Columns[1].GetCellContent(row).Parent;
            tbNameUpdate.Text = ((TextBlock)name.Content).Text;
            DataGridCell phone = (DataGridCell)dataGrid.Columns[2].GetCellContent(row).Parent;
            tbPhoneUpdate.Text = ((TextBlock)phone.Content).Text;
            DataGridCell email = (DataGridCell)dataGrid.Columns[3].GetCellContent(row).Parent;
            tbEmailUpdate.Text = ((TextBlock)email.Content).Text;
            DataGridCell address = (DataGridCell)dataGrid.Columns[4].GetCellContent(row).Parent;
            tbAddressUpdate.Text = ((TextBlock)address.Content).Text;
            DataGridCell postalZip = (DataGridCell)dataGrid.Columns[5].GetCellContent(row).Parent;
            tbPostalzipUpdate.Text = ((TextBlock)postalZip.Content).Text;
        }
    }
yacmzcpb

yacmzcpb1#

因为您使用的是Visual元素,而不是它们所表示的数据。
我对您使用的数据类型和体系结构并没有完全的了解,因此,我的示例并不是精确的实现,而是展示了实现的途径。

public partial class MainWindow : Window
    {
        hospitalEntities hp = new hospitalEntities();
        private readonly ObservableCollection<PatientEntity> patients = new(); 
        public MainWindow()
        {
            InitializeComponent();

            // Setting once after initialization XAML.
            dgPatientTable.ItemsSource = patients;
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            InitializeTable();
        }

        private void InitializeTable()
        {
            patients.Clear();
            hp.patients.ToList().ForEach(p => patients.Add(p));
        }

        int patientId = 0;
        private void dgPatientTable_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            DataGrid dataGrid = sender as DataGrid;
            if(dataGrid.SelectedItem is PatientEntity patient)
            {
                // Some code that works with the selected patient.
            }
        }

您也无法正确使用“新增”和“更新”区域。但为了显示范例,您的版面配置的XAML很重要。
请在您的问题中发布。
我找不到这句话背后的逻辑:lblID.Content =标识.内容;我只是想知道为什么它不起作用。原因是什么?
因为从ItemContainerGenerator中获取的不是数据(patient),而是表示它们的UI元素。要获取数据,只需从dataGrid.SelectedItem中提取数据并将其转换为原始类型。但您无法执行此操作。因为您的查询将返回一个具有匿名类的列表。而且您无法将SelectedItem转换为匿名类。
因此,首先需要为源DataGrid创建一个集合。此集合必须是命名类型,以便可以将SelectedItem强制转换为该类型。

相关问题