Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 绑定集合列表框数据网格_C#_Wpf_Xaml - Fatal编程技术网

C# 绑定集合列表框数据网格

C# 绑定集合列表框数据网格,c#,wpf,xaml,C#,Wpf,Xaml,我有两个数据库表:Account和AccountRecords。它们通过外键连接,因为每个帐户都包含多个记录。我使用ObservableCollection将列表框与帐户绑定: <ListBox Name="ListAccount" ItemsSource="{Binding CurrentHouse.Account}"> <ListBox.ItemTemplate> <DataTemplate> <Grid&g

我有两个数据库表:Account和AccountRecords。它们通过外键连接,因为每个帐户都包含多个记录。我使用ObservableCollection将列表框与帐户绑定:

<ListBox Name="ListAccount"
         ItemsSource="{Binding CurrentHouse.Account}">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <Grid>
        <TextBlock>
          <TextBlock.Text>
            <MultiBinding StringFormat="{}{0} {1}">
              <Binding Path="AccountNumber" />
              <Binding Path="Name" />
            </MultiBinding>
          </TextBlock.Text>
        </TextBlock>
      </Grid>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

然后将DataGrid与列表框中的选定项绑定:

<DataGrid ItemsSource="{Binding ElementName=ListAccount, Path=SelectedItems}">
  <DataGrid.Columns>
    <DataGridTextColumn Binding="{AccountNumber}"
                        Header="Nr"
                        FontSize="16" />
    <DataGridTextColumn Binding="{Name}"
                        Header="Name"
                        FontSize="16" />
  </DataGrid.Columns>

一切都好。我的问题是如何在DataGrid中显示每个帐户的记录?记录在单独的表格中。如果我创建了第二个可观察的集合,那么如何在DataGrid中显示记录和帐户

多谢各位。
Georg

您可以使用RowDetails模板。示例代码如下:

XAML:

<Window x:Class="TestWPFApp.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestWPFApp"
    Title="MainWindow" Height="350" Width="525">

<Grid>
    <DataGrid ItemsSource="{Binding AccountList}" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding AccountNumber}" Header="Account Number" FontSize="16"/>
            <DataGridTextColumn Binding="{Binding Name}" Header="Name" FontSize="16"/>
        </DataGrid.Columns>
        <DataGrid.RowDetailsTemplate>
            <DataTemplate>
                <DataGrid ItemsSource="{Binding RecordList,Mode=TwoWay}" AutoGenerateColumns="False">
                    <DataGrid.Columns>
                        <DataGridTextColumn Binding="{Binding RecordNumber}" Header="Record Number" FontSize="16"/>
                        <DataGridTextColumn Binding="{Binding Name}" Header="Name" FontSize="16"/>
                    </DataGrid.Columns>
                </DataGrid>
            </DataTemplate>
        </DataGrid.RowDetailsTemplate>
    </DataGrid>
</Grid>
</Window>

代码隐藏:

using System.Collections.ObjectModel;
using System.Windows;

namespace TestWPFApp
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new ViewModel();
        }
    }


    public class ViewModel
    {
        public ViewModel()
        {
            //Sample Data
            var recordList = new ObservableCollection<Record>();
            recordList.Add(new Record() { RecordNumber = "R1", Name = "R-Name-1" });
            recordList.Add(new Record() { RecordNumber = "R2", Name = "R-Name-2" });
            recordList.Add(new Record() { RecordNumber = "R3", Name = "R-Name-3" });
            recordList.Add(new Record() { RecordNumber = "R4", Name = "R-Name-4" });

            AccountList = new ObservableCollection<Account>();
            AccountList.Add(new Account() { AccountNumber = "A1111", Name = "A-Name-1", RecordList = recordList });
            AccountList.Add(new Account() { AccountNumber = "A2222", Name = "A-Name-2", RecordList = recordList });
            AccountList.Add(new Account() { AccountNumber = "A3333", Name = "A-Name-3", RecordList = recordList });
            AccountList.Add(new Account() { AccountNumber = "A4444", Name = "A-Name-4", RecordList = recordList });
        }
        public ObservableCollection<Account> AccountList { get; set; }
    }

    public class Account
    {
        public string AccountNumber { get; set; }
        public string Name { get; set; }
        public ObservableCollection<Record> RecordList { get; set; }
    }

    public class Record
    {
        public string RecordNumber { get; set; }
        public string Name { get; set; }
    }
}
使用System.Collections.ObjectModel;
使用System.Windows;
命名空间TestWPFApp
{
/// 
///MainWindow.xaml的交互逻辑
/// 
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
this.DataContext=newviewmodel();
}
}
公共类视图模型
{
公共视图模型()
{
//样本数据
var recordList=新的ObservableCollection();
添加(新记录(){RecordNumber=“R1”,Name=“R-Name-1”});
添加(新记录(){RecordNumber=“R2”,Name=“R-Name-2”});
添加(新记录(){RecordNumber=“R3”,Name=“R-Name-3”});
添加(新记录(){RecordNumber=“R4”,Name=“R-Name-4”});
AccountList=新的ObservableCollection();
AccountList.Add(新帐户(){AccountNumber=“A1111”,Name=“A-Name-1”,RecordList=RecordList});
AccountList.Add(新帐户(){AccountNumber=“A2222”,Name=“A-Name-2”,RecordList=RecordList});
AccountList.Add(新帐户(){AccountNumber=“a333”,Name=“A-Name-3”,RecordList=RecordList});
AccountList.Add(新帐户(){AccountNumber=“A4444”,Name=“A-Name-4”,RecordList=RecordList});
}
公共ObservableCollection帐户列表{get;set;}
}
公共类帐户
{
公共字符串AccountNumber{get;set;}
公共字符串名称{get;set;}
公共ObservableCollection记录列表{get;set;}
}
公开课记录
{
公共字符串记录编号{get;set;}
公共字符串名称{get;set;}
}
}
公共类账户
{
public int AccountNumber{get;set;}
公共字符串名称{get;set;}
}
公共类会计记录
{
public int AccountNumber{get;set;}
public int AccountRecordNumber{get;set;}
公共字符串详细信息{get;set;}
}
公共类会计经理
{
公共静态列表GetAccounts()
{
列表帐户=新列表()
{
新帐户(){AccountNumber=1,Name=“Account 1”},
新帐户(){AccountNumber=2,Name=“Account 2”}
};
归还账户;
}
公共静态列表GetAccountRecords(int accountNumber)
{
列表记录=新列表()
{
new AccountRecords(){AccountNumber=1,AccountRecordNumber=1,Details=“1.1记录”},
new AccountRecords(){AccountNumber=1,AccountRecordNumber=2,Details=“1.2记录”},
new AccountRecords(){AccountNumber=2,AccountRecordNumber=3,Details=“2.2记录”},
new AccountRecords(){AccountNumber=2,AccountRecordNumber=4,Details=“2.4记录”},
new AccountRecords(){AccountNumber=2,AccountRecordNumber=5,Details=“2.5记录”},
};
返回记录。其中(q=>q.AccountNumber==AccountNumber).ToList();
}
}
公共类BindingRelationalDataViewModel:INotifyPropertyChanged
{
公共列表帐户{get;set;}
私人会计记录清单;
公共会计记录列表
{
获取{返回currentAccountRecords;}
设置
{
currentAccountRecords=值;
RaisePropertyChanged(“CurrentAccountRecords”);
}
}
公共绑定RelationalDataViewModel()
{
Accounts=AccountManager.GetAccounts();
CollectionViewSource.GetDefaultView(Accounts).CurrentChanged+=new EventHandler(BindingRelationalDataViewModel\u CurrentChanged);
}
void BindingRelationalDataViewModel_CurrentChanged(对象发送方,事件参数e)
{
int accountNumber=((帐户)CollectionViewSource.GetDefaultView(帐户).CurrentItem).accountNumber;
CurrentAccountRecords=AccountManager.GetAccountRecords(accountNumber);
}
公共事件属性更改事件处理程序属性更改;
私有void RaisePropertyChanged(字符串propertyName)
{
if(PropertyChanged!=null)
{
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
}
XAML



您看过WPF DataGrid的RowDetailsTemplate了吗?我试过您的代码,它运行正常。唯一的问题是,我必须单击DataGrid.Columns(例如AccountNumber)以使
    public class Account
{
    public int AccountNumber { get; set; }
    public string Name { get; set; }
}

public class AccountRecords
{
    public int AccountNumber { get; set; }
    public int AccountRecordNumber { get; set; }
    public string Details { get; set; }
}

public class AccountManager
{
    public static List<Account> GetAccounts()
    {
        List<Account> accounts = new List<Account>()
            {
                new Account() { AccountNumber = 1, Name = "Account 1"},
                new Account() { AccountNumber = 2, Name = "Account 2"}
            };
        return accounts;
    }

    public static List<AccountRecords> GetAccountRecords(int accountNumber)
    {
        List<AccountRecords> records = new List<AccountRecords>()
            {
                new AccountRecords() {AccountNumber = 1, AccountRecordNumber = 1, Details = "1.1 record"},
                new AccountRecords() {AccountNumber = 1, AccountRecordNumber = 2, Details = "1.2 record"},
                new AccountRecords() {AccountNumber = 2, AccountRecordNumber = 3, Details = "2.2 record"},
                new AccountRecords() {AccountNumber = 2, AccountRecordNumber = 4, Details = "2.4 record"},
                new AccountRecords() {AccountNumber = 2, AccountRecordNumber = 5, Details = "2.5 record"},
            };
        return records.Where(q => q.AccountNumber == accountNumber).ToList();
    }
}

public class BindingRelationalDataViewModel : INotifyPropertyChanged
{
    public List<Account> Accounts { get; set; }

    private List<AccountRecords> currentAccountRecords;
    public List<AccountRecords> CurrentAccountRecords
    {
        get { return currentAccountRecords; }
        set
        {
            currentAccountRecords = value;
            RaisePropertyChanged("CurrentAccountRecords");
        }
    }

    public BindingRelationalDataViewModel()
    {
        Accounts = AccountManager.GetAccounts();
        CollectionViewSource.GetDefaultView(Accounts).CurrentChanged += new EventHandler(BindingRelationalDataViewModel_CurrentChanged);
    }

    void BindingRelationalDataViewModel_CurrentChanged(object sender, EventArgs e)
    {
        int accountNumber = ((Account)CollectionViewSource.GetDefaultView(Accounts).CurrentItem).AccountNumber;
        CurrentAccountRecords = AccountManager.GetAccountRecords(accountNumber);
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private  void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
<Window x:Class="StackOverFlowQuestions.BindingRelationalData"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:StackOverFlowQuestions"
    Title="BindingRelationalData" Height="300" Width="300">
<Window.Resources>
    <local:BindingRelationalDataViewModel x:Key="BindingRelationalDataViewModel"></local:BindingRelationalDataViewModel>
</Window.Resources>
<StackPanel DataContext="{Binding Source={StaticResource ResourceKey=BindingRelationalDataViewModel}}">
    <ListBox Name="ListAccount" ItemsSource="{Binding Path=Accounts}" IsSynchronizedWithCurrentItem="True">
        <ListBox.ItemTemplate>
            <DataTemplate >
                <Grid>
                    <TextBlock>
                            <TextBlock.Text>
                                <MultiBinding StringFormat="{}{0} {1}" >
                                    <Binding Path="AccountNumber" />
                                    <Binding Path="Name" />
                                </MultiBinding>
                            </TextBlock.Text>
                    </TextBlock>
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

    <DataGrid ItemsSource="{Binding Path=CurrentAccountRecords}" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding AccountRecordNumber}" Header="Nr" FontSize="16"/>
            <DataGridTextColumn Binding="{Binding Details}" Header="Name" FontSize="16"/>
        </DataGrid.Columns>
    </DataGrid>
</StackPanel>