设置 AutoGenerateColumns=true 并按数据类型自动转换
Set AutoGenerateColumns=true and auto convert by the DataType
我有一个很大的 ObservableCollection,其中包含 40 多个不同类型的列。
一些列是列表。
我不想设置 AutoGenerateColumns=false 因为列的 amont 但数据网格在数据类型的字符串中显示它:System.Collection.Generic.List'1[System.double]
我想呈现一个字符串,如“10,2,30,5.2”
如果它是一个列表,我可以创建一个转换器来检查值的类型和 return 这样的字符串吗?
我如何从 Xaml 读取它(我使用 mvvm patteren)
谢谢!
WPF 的 DataGrid
列引发一个 AutoGeneratingColumn
事件,您可以使用该事件为一个或多个列自定义列的生成。它可以像更改列 header 一样简单,也可以像用您自己的自定义列模板替换 auto-generated 列一样复杂。有关示例,请参阅 this MSDN link。
一个选项可能是将数据类型从 List 更改为您自己的 class 从 List 继承并覆盖 ToString 方法以 return 您想要的字符串。像这样:
public class MyDoubleList : List<double>
{
public override string ToString()
{
string s = "";
foreach (double d in this)
{
s = s + d.ToString() + ";";
}
return s;
}
}
用法示例:
MyDoubleList l = new MyDoubleList();
l.Add(12);
l.Add(25);
string a = l.ToString();
有多种方法可以解决您的问题。您可以使用已更改的集合元素创建新的 ViewModel 以进行显示,或者在显示时更改 ViewModel 外部的数据。第二种方法使用在显示时更改自动生成列的概念。 MSDN
中的操作方法文章中描述了这种方法
好处是您可以使用这种方法对任何列执行任何操作,而无需创建单独的 类。
在下面的示例中,我正在更改 State Collection 的显示。
您需要处理 AutoGeneratingColumn 事件。
<DataGrid x:Name="Dgrd" Canvas.Left="20" Canvas.Top="20" AutoGeneratingColumn="Dgrd_AutoGeneratingColumn" />
用于显示集合元素的数据模板。
<DataTemplate x:Key="CollectionTemplate">
<TextBlock Text="{Binding}" Loaded="TextBlock_Loaded" />
</DataTemplate>
更改集合列的 AutoGeneratingColumn 事件处理程序:
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 的 TextBlock 的 Loaded 事件处理程序实际更改我们的收集数据以显示:
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;
}
数据相关 类 :
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();
显示:
我有一个很大的 ObservableCollection,其中包含 40 多个不同类型的列。 一些列是列表。 我不想设置 AutoGenerateColumns=false 因为列的 amont 但数据网格在数据类型的字符串中显示它:System.Collection.Generic.List'1[System.double] 我想呈现一个字符串,如“10,2,30,5.2” 如果它是一个列表,我可以创建一个转换器来检查值的类型和 return 这样的字符串吗? 我如何从 Xaml 读取它(我使用 mvvm patteren) 谢谢!
WPF 的 DataGrid
列引发一个 AutoGeneratingColumn
事件,您可以使用该事件为一个或多个列自定义列的生成。它可以像更改列 header 一样简单,也可以像用您自己的自定义列模板替换 auto-generated 列一样复杂。有关示例,请参阅 this MSDN link。
一个选项可能是将数据类型从 List 更改为您自己的 class 从 List 继承并覆盖 ToString 方法以 return 您想要的字符串。像这样:
public class MyDoubleList : List<double>
{
public override string ToString()
{
string s = "";
foreach (double d in this)
{
s = s + d.ToString() + ";";
}
return s;
}
}
用法示例:
MyDoubleList l = new MyDoubleList();
l.Add(12);
l.Add(25);
string a = l.ToString();
有多种方法可以解决您的问题。您可以使用已更改的集合元素创建新的 ViewModel 以进行显示,或者在显示时更改 ViewModel 外部的数据。第二种方法使用在显示时更改自动生成列的概念。 MSDN
中的操作方法文章中描述了这种方法好处是您可以使用这种方法对任何列执行任何操作,而无需创建单独的 类。
在下面的示例中,我正在更改 State Collection 的显示。
您需要处理 AutoGeneratingColumn 事件。
<DataGrid x:Name="Dgrd" Canvas.Left="20" Canvas.Top="20" AutoGeneratingColumn="Dgrd_AutoGeneratingColumn" />
用于显示集合元素的数据模板。
<DataTemplate x:Key="CollectionTemplate"> <TextBlock Text="{Binding}" Loaded="TextBlock_Loaded" /> </DataTemplate>
更改集合列的 AutoGeneratingColumn 事件处理程序:
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 的 TextBlock 的 Loaded 事件处理程序实际更改我们的收集数据以显示:
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; }
数据相关 类 :
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();
显示: