用自定义对象绑定C#数据网格

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用自定义对象绑定C#数据网格相关的知识,希望对你有一定的参考价值。

我试图在数据网格中显示账户数据,但绑定似乎并不正确。

public ObservableCollection<AccountData> accountlist = new ObservableCollection<AccountData>();

public MainWindow()
        
            InitializeComponent();
            AccountDataGrid.ItemsSource = accountlist;
        

这是我的列表的样子,以及我如何将其绑定到数据网格中。

GetAccountsResponse resp = GetAccountsResponse.GetAccounts(m_authImpl);

            List<AccountData> accounts = resp.Accounts;
            for (int i = 0; i < accounts.Count; ++i)
            
                AccountData account = accounts[i];
                accountlist.Add(account);
            

我使用一个API来获取账户数据,然后将其放入我的可观察账户列表中。

<DataGrid x:Name="AccountDataGrid" HorizontalAlignment="Left" Height="249" Margin="10,278,0,0" VerticalAlignment="Top" Width="772" AutoGenerateColumns="False" IsReadOnly="True" >
            <DataGrid.Columns>
                <DataGridTextColumn Header="Type"  Binding="Binding Path=m_type"/>
                <DataGridTextColumn Header="Number"  Binding="Binding Path=m_number"/>
                <DataGridTextColumn Header="Status"  Binding="Binding Path=m_status"/>
                <DataGridTextColumn Header="isPrimary"  Binding="Binding Path=m_isPrimary"/>
                <DataGridTextColumn Header="isBilling"  Binding="Binding Path=m_isBilling"/>
                <DataGridTextColumn Header="clientAccountType"  Binding="Binding Path=m_clientAccountType"/>
            </DataGrid.Columns>
        </DataGrid>

这是我的数据网格的代码

public class AccountData
    
        public UserAccountType m_type;
        public string m_number;
        public AccountStatus m_status;
        public bool m_isPrimary;
        public bool m_isBilling;
        public ClientAccountType m_clientAccountType;

        public AccountData();
    

这就是我的对象的样子!

一些backstory:accountlist在调试器中拥有所有正确的信息,但当在数据网格中显示结果时,它显示为一个空白条目。

public enum UserAccountType
    
        Undefined = 0,
        Cash = 1,
        Margin = 2,
        TFSA = 3,
        RRSP = 4,
        SRRSP = 5,
        LRRSP = 6,
        LIRA = 7,
        LIF = 8,
        RIF = 9,
        SRIF = 10,
        LRIF = 11,
        RRIF = 12,
        PRIF = 13,
        RESP = 14,
        FRESP = 15,
        FX = 16,
        FXD = 17,
        Count = 18
    
public enum AccountStatus
    
        Undefined = -1,
        UnAllocated = 0,
        Active = 1,
        SuspendedClosed = 2,
        SuspendedViewOnly = 3,
        LiquidateOnly = 4,
        Closed = 5,
        Count = 6
    
public enum ClientAccountType
    
        Undefined = 0,
        Individual = 1,
        Joint = 2,
        InformalTrust = 3,
        Corporation = 4,
        InvestmentClub = 5,
        FormalTrust = 6,
        Partnership = 7,
        SoleProprietorship = 8,
        Family = 9,
        JointAndInformalTrust = 10,
        Institution = 11,
        Count = 12
    
答案

让我们用 MVVM. 该方法的主要目标是:对数据所做的任何更改都会立即显示在以下内容中。DataGrid 在飞行中。

你需要一个实现了 INotifyPropertyChanged 界面

NotifyPropertyChanged.cs。

public class NotifyPropertyChanged : INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
        => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

然后将新的数据类派生为 NotifyPropertyChanged. 为便于比较,可采用以下方法: AccountData 类中,我为构造函数添加了一个重载,并加入了 AccountData 参数。

UIAccountData.cs

public class UIAccountData : NotifyPropertyChanged

    private UserAccountType m_type;
    private string m_number;
    private AccountStatus m_status;
    private bool m_isPrimary;
    private bool m_isBilling;
    private ClientAccountType m_clientAccountType;

    public UserAccountType Type
    
        get => m_type;
        set
        
            m_type = value;
            OnPropertyChanged();
        
    
    public string Number
    
        get => m_number;
        set
        
            m_number = value;
            OnPropertyChanged();
        
    
    public AccountStatus Status
    
        get => m_status;
        set
        
            m_status = value;
            OnPropertyChanged();
        
    
    public bool IsPrimary
    
        get => m_isPrimary;
        set
        
            m_isPrimary = value;
            OnPropertyChanged();
        
    
    public bool IsBilling
    
        get => m_isBilling;
        set
        
            m_isBilling = value;
            OnPropertyChanged();
        
    
    public ClientAccountType ClientAccountType
    
        get => m_clientAccountType;
        set
        
            m_clientAccountType = value;
            OnPropertyChanged();
        
    

    public UIAccountData()  

    public UIAccountData(AccountData account)
    
        m_type = account.m_type;
        m_number = account.m_number;
        m_status = account.m_status;
        m_isPrimary = account.m_isPrimary;
        m_isBilling = account.m_isBilling;
        m_clientAccountType = account.m_clientAccountType;
    

    public AccountData ToAccountData => new AccountData
    
        m_type = m_type,
        m_number = m_number,
        m_status = m_status,
        m_isPrimary = m_isPrimary,
        m_isBilling = m_isBilling,
        m_clientAccountType = m_clientAccountType,
    ;

然后创建包含集合并用于Bindings的主类。

MainViewModel.cs

public class MainViewModel : NotifyPropertyChanged

    public ObservableCollection<UIAccountData> _accountlist;

    public ObservableCollection<UIAccountData> Accountlist
    
        get => _accountlist;
        set
        
            _accountlist = value;
            OnPropertyChanged();
        
    

    public MainViewModel()
    
        // demo values
        Accountlist = new ObservableCollection<UIAccountData>
        
            new UIAccountData  Type = UserAccountType.Cash, Number = "123", Status = AccountStatus.Active, IsPrimary = true, IsBilling = true, ClientAccountType = ClientAccountType.Individual ,
            new UIAccountData  Type = UserAccountType.Margin, Number = "aaa", Status = AccountStatus.Active, IsPrimary = false, IsBilling = true, ClientAccountType = ClientAccountType.InformalTrust ,
            new UIAccountData  Type = UserAccountType.LRRSP, Number = "bbb", Status = AccountStatus.SuspendedClosed, IsPrimary = true, IsBilling = false, ClientAccountType = ClientAccountType.Partnership ,
            new UIAccountData  Type = UserAccountType.SRIF, Number = "456", Status = AccountStatus.SuspendedViewOnly, IsPrimary = false, IsBilling = false, ClientAccountType = ClientAccountType.Institution ,
        ;
        AccountData account = new AccountData()  m_type = UserAccountType.FX, m_number = "fff", m_status = AccountStatus.SuspendedViewOnly, m_isPrimary = true, m_isBilling = false, m_clientAccountType = ClientAccountType.Institution ;
        Accountlist.Add(new UIAccountData(account));
    

完整的标记

MainWindow.xaml

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApp1"
        Title="MainWindow" Height="600" Width="1000" WindowStartupLocation="CenterScreen">
    <Window.DataContext>
        <local:MainViewModel/><!-- MainViewModel attached here -->
    </Window.DataContext>
    <Grid>
        <DataGrid ItemsSource="Binding Accountlist" HorizontalAlignment="Left" AutoGenerateColumns="False" IsReadOnly="True" Width="Auto">
            <DataGrid.Columns>
                <DataGridTextColumn Width="*" Header="Type" Binding="Binding Type"/>
                <DataGridTextColumn Width="*" Header="Number" Binding="Binding Number"/>
                <DataGridTextColumn Width="*" Header="Status" Binding="Binding Status"/>
                <DataGridCheckBoxColumn Width="*" Header="IsPrimary" Binding="Binding IsPrimary"/>
                <DataGridCheckBoxColumn Width="*" Header="IsBilling" Binding="Binding IsBilling"/>
                <DataGridTextColumn Width="*" Header="ClientAccountType" Binding="Binding ClientAccountType"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

最后

MainWindow.xaml.cs

public partial class MainWindow : Window

    public MainWindow()
    
        InitializeComponent();
    

DataGrid MVVM

另一答案

WPF绑定不支持字段,原因很明显(违反封装)。

克服这个问题的最简单的方法是将你的公共字段转换为属性。

public class AccountData

    public UserAccountType m_type  get; set; 
    public string m_number  get; set; 
    public AccountStatus m_status  get; set; 
    public bool m_isPrimary  get; set; 
    public bool m_isBilling  get; set; 
    public ClientAccountType m_clientAccountType  get; set; 

    public AccountData()  /* . . . */ 

以上是关于用自定义对象绑定C#数据网格的主要内容,如果未能解决你的问题,请参考以下文章

@RequestBody接收Json参数 用自定义注解对Vo对象中Date类型日期格式校验

C# 用自定义错误完成后台工作人员

用自定义方法,传入成绩数组,实现输出考试成绩的成三名

WPF 动态列(DataGridTemplateColumn) 绑定数据 (自定义控件)对象绑定

带有自定义列的 WPF 数据网格绑定

如何维护多个Frame和多个相应对象之间的数据绑定?