动态生成列mvvm

我尝试使用动态生成列创建ListView。 我用mvvm patern。 我该如何实现呢? 在这个momemt我只有静态列。

          

您可以使用转换器动态创建具有适当列的GridView 。 这是工作示例:

应用程序屏幕截图

MainWindow.xaml

       

MainWindow.xaml.cs

 using System.Collections.Generic; using System.Windows; namespace WpfApplication1 { ///  /// Interaction logic for MainWindow.xaml ///  public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); DataContext = new ViewModel(); } } public class ViewModel { public ColumnConfig ColumnConfig { get; set; } public IEnumerable Products { get; set; } public ViewModel() { Products = new List { new Product { Name = "Some product", Attributes = "Very cool product" }, new Product { Name = "Other product", Attributes = "Not so cool one" } }; ColumnConfig = new ColumnConfig { Columns = new List { new Column { Header = "Name", DataField = "Name" }, new Column { Header = "Attributes", DataField = "Attributes" } } }; } } public class ColumnConfig { public IEnumerable Columns { get; set; } } public class Column { public string Header { get; set; } public string DataField { get; set; } } public class Product { public string Name { get; set; } public string Attributes { get; set; } } } 

ConfigToDynamicGridViewConverter.cs

 using System; using System.Globalization; using System.Windows.Controls; using System.Windows.Data; namespace WpfApplication1 { public class ConfigToDynamicGridViewConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var config = value as ColumnConfig; if (config != null) { var grdiView = new GridView(); foreach (var column in config.Columns) { var binding = new Binding(column.DataField); grdiView.Columns.Add(new GridViewColumn {Header = column.Header, DisplayMemberBinding = binding}); } return grdiView; } return Binding.DoNothing; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotSupportedException(); } } } 

谢谢谢尔盖,获得了一个了不起的答案。

我以稍微不同的forms使用它,因为我需要添加具有非文本数据类型的列。

因此,对Sergei的答案的以下修改允许您对数据值使用ContentControl包装器。 然后,它们将根据为每个单元格中的值定义的DataTemplates进行渲染。

如果使用ContentControlDataField而不是TextDataField(最初为DataField),则将包装该列:

  public class ConfigToDynamicGridViewConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var config = value as ColumnConfig; if (config != null) { var grdiView = new GridView(); foreach (var column in config.Columns) { bool cc = !string.IsNullOrEmpty(column.ContentControlDataField); var binding = new Binding(cc ? column.ContentControlDataField : column.TextDataField); if (cc) { var template = new DataTemplate(); var fact = new FrameworkElementFactory(typeof(ContentControl)); fact.SetBinding(ContentControl.ContentProperty, binding); template.VisualTree = fact; grdiView.Columns.Add(new GridViewColumn {Header = column.Header, CellTemplate = template}); } else grdiView.Columns.Add(new GridViewColumn {Header = column.Header, DisplayMemberBinding = binding}); } return grdiView; } return Binding.DoNothing; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotSupportedException(); } } public class ColumnConfig { public IEnumerable Columns { get; set; } } public class Column { public string Header { get; set; } public string TextDataField { get; set; } public string ContentControlDataField { get; set; } }