设置AutoGenerateColumns = true并按DataType自动转换

时间:2015-12-10 09:13:00

标签: c# wpf mvvm binding converter

我有一个很大的ObservableCollection,有40多个列,它们具有相同的类型。 一些列是列表。 由于列的不对,我不想设置AutoGenerateColumns = false,但datagrid以数据类型的字符串形式显示:System.Collection.Generic.List' 1 [System.double] 我想呈现一个像" 10,2,30,5.2" 我可以创建一个检查值类型的转换器,如果它是一个列表,则返回这样的字符串吗? 我如何从Xaml中读取它(我使用mvvm patteren) 谢谢!

3 个答案:

答案 0 :(得分:3)

WPF的DataGrid列引发了一个AutoGeneratingColumn事件,您可以使用该事件为一个或多个列自定义列的生成。它可以像将列标题更改为使用您自己的自定义列模板替换自动生成的列一样复杂。有关示例,请参阅this MSDN link

答案 1 :(得分:2)

一个选项可能是将数据类型从List更改为继承自List的自己的类,并重写ToString方法以返回所需的字符串。像这样:

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();

答案 2 :(得分:1)

有多种方法可以解决您的问题。您可以使用更改的集合元素创建新的ViewModel以进行显示,或者在显示时更改ViewModel外部的数据。第二种方法使用在显示时更改AutoGenerated列的概念。 MSDN

中的操作方法文章对此方法进行了描述

好处是您可以使用此方法对任何列执行任何操作,而无需创建单独的类。

在下面的示例中,我正在更改State Collection的显示。

  1. 您需要处理AutoGeneratingColumn事件。

    <DataGrid x:Name="Dgrd" Canvas.Left="20" Canvas.Top="20" AutoGeneratingColumn="Dgrd_AutoGeneratingColumn"  />
    
  2. DataTemplate用于显示Collection元素。

        <DataTemplate x:Key="CollectionTemplate">            
            <TextBlock Text="{Binding}" Loaded="TextBlock_Loaded" />            
        </DataTemplate>     
    
  3. 更改集合列的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") };
          }
        }
    
  4. DataTemplate的TextBlock的已加载事件处理程序,用于实际更改要显示的集合数据:

        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;
        }     
    
  5. 数据相关课程:

    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; }
    }
    
  6. Dgrd.ItemsSource = new DataStore();

  7. 显示:

    DataGrid Autogenerated column changed