AvinashKumarVerma Ответов: 1

Datagrid не показывает данные в WPF


код XAML :
<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525"
    Loaded="Window_Loaded">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="272*"/>
            <RowDefinition Height="71*"/>
        </Grid.RowDefinitions>

        <Button Content="Synchronize" Name="btnsync" Grid.Row="1" FontSize="40" FontFamily="Times New Roman" FontWeight="ExtraBold"/>
        <DataGrid Name="dgEmp" AutoGenerateColumns="False" ColumnWidth="*">
            <DataGrid.Columns>
                <DataGridTextColumn Header="EmpNo" Binding="{Binding EmpNo}" ></DataGridTextColumn>
                <DataGridTextColumn Header="EmpName" Binding="{Binding EmpName}" ></DataGridTextColumn>
                <DataGridTextColumn Header="Salary" Binding="{Binding Salary}" ></DataGridTextColumn>
                <DataGridTextColumn Header="DeptName" Binding="{Binding DeptName}" ></DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>



Файл MainWindow.язык XAML.VB кода
Система Импорта.Коллекции.Модель

Класс MainWindow

Служащий Государственного Класса
Public EmpNo Как Строка
Public EmpName В Виде Строки
Оплаты Труда Государственных Служащих Как Строку
Общественные DeptName Как Строку
End Класса

Дим empList как новые коллекции ObservableCollection(работника)

Private Sub btnsync_Click(отправитель как система.Объект, как система.Окна.RoutedEventArgs) обрабатывает btnsync.Щелчок
'empList.Добавить(Новый Сотрудник() С {.EmpNo = "2", .Столбец Empname = "Авинаш", .Зарплата = "5000", .DeptName = "Дев"})
-дгемп.Предметы.Освежить()
Конец Подводной Лодки

Private Sub Window_Loaded(отправитель как система.Объект, как система.Окна.RoutedEventArgs) Обрабатывает MyBase.Нагруженный
empList.Добавить(Новый Сотрудник() С {.EmpNo = "2", .Столбец Empname = "Авинаш", .Зарплата = "5000", .DeptName = "Дев"})
empList.Добавить(Новый Сотрудник() С {.EmpNo = "3", .Столбец Empname = "Авинаш", .Зарплата = "5000", .DeptName = "Дев"})
empList.Добавить(Новый Сотрудник() С {.EmpNo = "4", .Столбец Empname = "Авинаш", .Зарплата = "5000", .DeptName = "Дев"})
дгемп.ItemsSource = empList

Конец Подводной Лодки

Private Sub dgEmp_SelectionChanged(отправитель как система.Объект, как система.Окна.Управления.SelectionChangedEventArgs) обрабатывает dgEmp.SelectionChanged

Конец Подводной Лодки
End Класса

Что я уже пробовал:

Я проверил, что источник элементов имеет данные, но он не отображается на dataGrid.

Herman&lt;T&gt;.Instance

Я не вижу ItemsSource={привязки ...} в вашем XAML нет ни одной привязки SelectedItem={....}

Graeme_Grant

Это потому, что он не использует привязку данных XAML, он жестко кодирует в коде позади. Видеть:

 dgEmp.ItemsSource = empList

1 Ответов

Рейтинг:
12

Graeme_Grant

дигиманус[^] частично прав в своем комментарии выше.

Во-первых, чтобы DataGrid мог видеть коллекцию сотрудников, привязка данных должна видеть коллекцию как свойство MainWindow:

Public Property empList = New ObservableCollection(Of Employee)

Далее вы обнаружите кучу ошибок привязки данных в окне вывода отладки. Вот один из них в качестве примера:
System.Windows.Data Error: 40 : BindingExpression path error: 'EmpNo' property not found on 'object' ''Employee' (HashCode=62835574)'. BindingExpression:Path=EmpNo; DataItem='Employee' (HashCode=62835574); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')

Это происходит потому, что привязка данных ищет Properties и нет Fields Так что исправить это довольно просто:
Public Class Employee
    Public Property EmpNo As String
    Public Property EmpName As String
    Public Property Salary As String
    Public Property DeptName As String
End Class

Следующая проблема заключается в том, что вы увидите элементы, загруженные дважды в DataGrid. Причина этого в том, что вы слушаете Windows.Loaded событие как в XAML, так и в коде позади него. Вам нужно выбрать, какой из них сохранить. Я бы рекомендовал удалить его из XAML, чтобы соответствовать тому, как вы кодируете свой проект.

Последняя проблема, которая у вас возникнет, - это если вы обновите какие-либо свойства на себе Employee класс, они не будут отражены как Employee класс не реализует INotifyPropertyChanged Интерфейс.

Итак, ваш исправленный проект будет выглядеть так:
<Window x:Class="MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        mc:Ignorable="d"

        Title="MainWindow" Height="350" Width="525">
    
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="272*"/>
            <RowDefinition Height="71*"/>
        </Grid.RowDefinitions>

        <Button Content="Synchronize" Name="btnsync" Grid.Row="1" FontSize="40" FontFamily="Times New Roman" FontWeight="ExtraBold"/>
        <DataGrid Name="dgEmp" AutoGenerateColumns="False" ColumnWidth="*">
            <DataGrid.Columns>
                <DataGridTextColumn Header="EmpNo" Binding="{Binding EmpNo}" ></DataGridTextColumn>
                <DataGridTextColumn Header="EmpName" Binding="{Binding EmpName}" ></DataGridTextColumn>
                <DataGridTextColumn Header="Salary" Binding="{Binding Salary}" ></DataGridTextColumn>
                <DataGridTextColumn Header="DeptName" Binding="{Binding DeptName}" ></DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

а код-за спиной:
Imports System.Collections.ObjectModel

Class MainWindow
    Public Property empList = New ObservableCollection(Of Employee)

    Private Sub btnsync_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles btnsync.Click
        'empList.Add(New Employee() With {.EmpNo = "2", .EmpName = "Avinash", .Salary = "5000", .DeptName = "Dev"})
        'dgEmp.Items.Refresh()
    End Sub

    Private Sub Window_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
        empList.Add(New Employee() With {.EmpNo = "2", .EmpName = "Avinash", .Salary = "5000", .DeptName = "Dev"})
        empList.Add(New Employee() With {.EmpNo = "3", .EmpName = "Avinash", .Salary = "5000", .DeptName = "Dev"})
        empList.Add(New Employee() With {.EmpNo = "4", .EmpName = "Avinash", .Salary = "5000", .DeptName = "Dev"})
        dgEmp.ItemsSource = empList

    End Sub

    Private Sub dgEmp_SelectionChanged(sender As System.Object, e As System.Windows.Controls.SelectionChangedEventArgs) Handles dgEmp.SelectionChanged

    End Sub

End Class

Public Class Employee
    Public Property EmpNo As String
    Public Property EmpName As String
    Public Property Salary As String
    Public Property DeptName As String
End Class

Я бы рекомендовал ознакомиться с системой привязки данных, используемой в WPF: Microsoft Docs: привязка данных (WPF)[^]