问题
Student class
public class Student
{
string name;
List<SubjectInfo> subjectInfoList;
....
}
List<SubjectInfo>
List can have different number of SubjectInfo
objects for different students.
SubjectInfo class
public class SubjectInfo
{
string subjectCode;
int marks;
...
}
I want to display student object detail on a window. Since List have different number of object count I generated these from code behind.
int i = 10;
foreach (SubjectInfo info in student.SubjectInfoList)
{
TextBox tb = new TextBox();
tb.Width = 200;
tb.Height = 20;
tb.Margin = new Thickness(10, i, 0, 0);
StudentDataGrid.Children.Add(tb);
i += 60;
}
I would like to bind this List list from code behind. But I have no idea of doing that.
I want to bind marks property of student.SubjectInfoList
Please help me with binding list object properties from codebehind.
EDIT
This is the sample student object;
Student student = new Student("Joe", new List<SubjectInfo>() { new SubjectInfo("Subject1", 50), new SubjectInfo("Subject2", 70)});
My window should like this;

NOTE if student doing 4 subjects total TextBox
count is 5.
回答1:
Pure XAML solution:
<Window (... your window attributes) >
....
<Grid x:Name="StudentDataGrid">
<ListView ItemsSource="{Binding SubjectInfoList}">
<ListView.ItemTemplate>
<DataTemplate DataType="{x:Type local:SubjectInfo}">
<TextBox Text="{Binding Marks}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Window>
But to have it work you have to transform your fields to public properties:
public class Student
{
string name;
public List<SubjectInfo> SubjectInfoList { get; set; }
....
}
and:
public class SubjectInfo
{
string subjectCode;
public int Marks { get; set; }
...
}
UPDATE
XAML:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Grid x:Name="StudentGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="Student name :" Grid.Row="0" Grid.Column="0"/>
<TextBlock Text="Student marks :" Grid.Row="1" Grid.Column="0"/>
<TextBox Text="{Binding Name}" Grid.Row="0" Grid.Column="1" />
<ListView Grid.Row="1" Grid.Column="1" ItemsSource="{Binding SubjectInfoList}" BorderThickness="0">
<ListView.ItemTemplate>
<DataTemplate DataType="{x:Type local:SubjectInfo}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding SubjectCode}"/>
<TextBox Grid.Column="1" Text="{Binding Marks}"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Window>
The code:
using System.Collections.Generic;
using System.Windows;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Student student = new Student("Joe", new List<SubjectInfo>() { new SubjectInfo("Subject1", 50), new SubjectInfo("Subject2", 70) });
StudentGrid.DataContext = student;
}
}
public class Student
{
public string Name { get; set; }
public List<SubjectInfo> SubjectInfoList { get; set; }
public Student(string name, List<SubjectInfo> list)
{
Name = name;
SubjectInfoList = list;
}
}
public class SubjectInfo
{
public string SubjectCode { get; set; }
public int Marks { get; set; }
public SubjectInfo(string subjectCode, int marks)
{
SubjectCode = subjectCode;
Marks = marks;
}
}
}
回答2:
Better to do it in XAML. But if you really want to do it in code-behind, try this. Fields of SubjectInfo must be public.
foreach (SubjectInfo info in student.SubjectInfoList)
{
TextBox tb = new TextBox();
///...
tb.DataContext = info;
Binding binding = new Binding("marks");
tb.SetBinding(TextBox.TextProperty, binding);
///...
}
来源:https://stackoverflow.com/questions/14589200/binding-custom-list-object-properties-to-textbox-from-code-behind