Istnieją co najmniej trzy sposoby osiągnięcia tego celu:
- Modyfikuj kolumny DataGrid jest ręcznie z kodu źródłowego
- użytkowania DataTable jako ItemsSource *
Użyj CustomTypeDescriptor
* zalecane dla prostoty:
Pierwsze podejście: użyj kodu z tyłu, aby wygenerować kolumny DataGrid w czasie wykonywania. Jest to łatwe do wdrożenia, ale może wydawać się nieco hackish, szczególnie jeśli używasz MVVM. Tak, że masz DataGrid ze stałymi kolumnach:
<DataGrid x:Name="grid">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding id}" Header="id" />
<DataGridTextColumn Binding="{Binding image}" Header="image" />
</DataGrid.Columns>
</DataGrid>
Kiedy masz swoje „Names” gotowy, a następnie zmodyfikować siatkę przez dodawanie/usuwanie kolumn, np:
// add new columns to the data grid
void AddColumns(string[] newColumnNames)
{
foreach (string name in newColumnNames)
{
grid.Columns.Add(new DataGridTextColumn {
// bind to a dictionary property
Binding = new Binding("Custom[" + name + "]"),
Header = name
});
}
}
Będziemy chcieli Aby utworzyć klasę opakowania, która powinna zawierać klasę oryginalną oraz słownik zawierający niestandardowe właściwości. Załóżmy, że główny klasa wiersz jest „User”, po czym tylko chcesz klasy otoki coś takiego:
public class CustomUser : User
{
public Dictionary<string, object> Custom { get; set; }
public CustomUser() : base()
{
Custom = new Dictionary<string, object>();
}
}
zapełnić ItemsSource
z kolekcją tej nowej klasy „CustomUser”:
void PopulateRows(User[] users, Dictionary<string, object>[] customProps)
{
var customUsers = users.Select((user, index) => new CustomUser {
Custom = customProps[index];
});
grid.ItemsSource = customUsers;
}
Więc wiążąc je ze sobą, na przykład:
var newColumnNames = new string[] { "Name1", "Name2" };
var users = new User[] { new User { id="First User" } };
var newProps = new Dictionary<string, object>[] {
new Dictionary<string, object> {
"Name1", "First Name of First User",
"Name2", "Second Name of First User",
},
};
AddColumns(newColumnNames);
PopulateRows(users, newProps);
2-ty podejście: użyj DataTable. Wykorzystuje to niestandardową infrastrukturę pod maską, ale jest łatwiejsza w użyciu.Wystarczy powiązać DataGrid na ItemsSource
do DataTable.DefaultView
nieruchomości:
<DataGrid ItemsSource="{Binding Data.DefaultView}" AutoGenerateColumns="True" />
Następnie można zdefiniować kolumny jednak chcesz, np:
Data = new DataTable();
// create "fixed" columns
Data.Columns.Add("id");
Data.Columns.Add("image");
// create custom columns
Data.Columns.Add("Name1");
Data.Columns.Add("Name2");
// add one row as an object array
Data.Rows.Add(new object[] { 123, "image.png", "Foo", "Bar" });
3-ty podejście: skorzystać z rozciągliwości System typu .Net. W szczególności używaj CustomTypeDescriptor
. Umożliwia to tworzenie niestandardowego typu w czasie wykonywania; co z kolei pozwala powiedzieć DataGrid, że twój typ ma właściwości "Nazwa1", "Nazwa2", ... "NazwaN" lub cokolwiek innego chcesz. Zobacz here dla prostego przykładu tego podejścia.
jest to jedyny sposób wyświetlania tych informacji? –
Nie jestem pewien, o co pytasz. – Wr4thon
Johannes zobaczył moją odpowiedź, abyś mógł zobaczyć, dlaczego o to pytam. –