问题
I have a big ObservableCollection with 40+ columns that havn't the same type. Some of the columns are lists. I don't want to set AutoGenerateColumns=false because of the amont of the columns but the datagrid presents this in string of the datatype: System.Collection.Generic.List'1[System.double] and I want to present a string of the value like "10,2,30,5.2" Can I create a converter that check the typeof the value and return a string like this if it's a list? how can I read it from the Xaml (I use mvvm patteren) thanks!
回答1:
An option could be changing the datatype from List to your own class inheriting from List and overriding the ToString method to return the string you want. Something like this:
public class MyDoubleList : List<double>
{
public override string ToString()
{
string s = "";
foreach (double d in this)
{
s = s + d.ToString() + ";";
}
return s;
}
}
Usage sample:
MyDoubleList l = new MyDoubleList();
l.Add(12);
l.Add(25);
string a = l.ToString();
回答2:
WPF's DataGrid
column raises an AutoGeneratingColumn
event that you can use to customize the generation of columns for one or more of your columns. It could be as simple as changing the column header to as complex as replacing the auto-generated column with your own custom column template. See this MSDN link for some examples.
回答3:
There are various ways to address your issue. You can create a new ViewModel with changed collection elements for display, or change data outside the ViewModel while displaying. Second approach uses the concept of changing the AutoGenerated column while displaying. This approach is described in how-to article in MSDN
Benefit being that you can use this approach to do anything with any column without creating separate classes.
In example below, I am changing the display of State Collection.
You need to handle AutoGeneratingColumn event.
<DataGrid x:Name="Dgrd" Canvas.Left="20" Canvas.Top="20" AutoGeneratingColumn="Dgrd_AutoGeneratingColumn" />
DataTemplate for showing Collection elements.
<DataTemplate x:Key="CollectionTemplate"> <TextBlock Text="{Binding}" Loaded="TextBlock_Loaded" /> </DataTemplate>
AutoGeneratingColumn event handler to change Collection Column :
private void Dgrd_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) { if (e.PropertyType == typeof(ObservableCollection<State>)) { e.Column = new DataGridTemplateColumn() { Header = "StateList", CellTemplate = (DataTemplate)FindResource("CollectionTemplate") }; } }
DataTemplate's TextBlock's Loaded event handler to actually change our collection data to display :
private void TextBlock_Loaded(object sender, RoutedEventArgs e) { var country = (Country)((TextBlock)e.OriginalSource).DataContext; var states = country.States.Select(c => c.Area + " : " + c.Capital + " : " + c.Name); string state_string = ""; foreach (string s in states) { state_string = state_string + " ^ " + s; } ((TextBlock)e.OriginalSource).DataContext = state_string; }
Data related classes :
public class DataStore { public ObservableCollection<Country> Countries { get; set; } public DataStore() { Countries = new ObservableCollection<Country>(); Countries.Add(new Country() { Area = 12345, Capital = "NewDelhi", Formed = DateTime.Parse("1/1/1990"), Name = "India", States = new ObservableCollection<State>() { new State() { Area = 112345, Capital = "Bhopal", Name = "MP" }, new State() { Area = 113456, Capital = "Lucknow", Name = "UP" } } }); Countries.Add(new Country() { Area = 22345, Capital = "Washington DC", Formed = DateTime.Parse("1/1/1995"), Name = "USA", States = new ObservableCollection<State>() { new State() { Area = 212345, Capital = "Silicon Valley", Name = "Pennysylvania" }, new State() { Area = 213456, Capital = "NewYork", Name = "Old Trafford" } } }); } } public class Country { public string Name { get; set; } public int Area { get; set; } public string Capital { get; set; } public DateTime Formed { get; set; } public ObservableCollection<State> States { get; set; } } public class State { public string Name { get; set; } public int Area { get; set; } public string Capital { get; set; } }
Dgrd.ItemsSource = new DataStore();
Display :
来源:https://stackoverflow.com/questions/34197738/set-autogeneratecolumns-true-and-auto-convert-by-the-datatype