2014-11-28 3 views
0

Я пытаюсь связать ObservableCollection с строками данных в моем datagrid. Я собираюсь сделать само обновление Datagrid (если данные добавлены), это не сработало при использовании DataTable. Я протестировал этот подход, и он работает отлично, мой datagrid привязан к свойству ResultTable, а имена свойств - имена столбцов.WPF привязка DataGrid с ObservableCollection

public class MainWindowViewModel 
{ 
    public MainWindowViewModel() 
    { 
     ResultTable = new ObservableCollection<Row>(); 
     ResultTable.Add(new Row() { Name = "Peter", Age = "21", Sex = "Male" }); 
     ResultTable.Add(new Row() { Name = "Sara", Age = "25", Sex = "Female" }); 
     ResultTable.Add(new Row() { Name = "Mike", Age = "28", Sex = "Male" }); 
    } 

    public ObservableCollection<Row> ResultTable { get; set; } 
} 

public class Row 
{ 
    public string Name { get; set; } 
    public string Age { get; set; } 
    public string Sex { get; set; } 
} 

Теперь, мой вопрос: как я могу сделать это динамически? Это был мой второй подход и выглядит, как будто ничего в DataGrid ...

public class MainWindowViewModel 
{ 
    public MainWindowViewModel() 
    { 
     ResultTable = new ObservableCollection<Row>(); 
     var row = new Row(); 
     row.Columns.Add(new Item() { Name = "Name", Value = "Peter" }); 
     row.Columns.Add(new Item() { Name = "Age", Value = "21" }); 
     row.Columns.Add(new Item() { Name = "Sex", Value = "Male" }); 
     ResultTable.Add(row); 
    } 

    public ObservableCollection<Row> ResultTable { get; set; } 
} 

public class Row 
{ 
    public List<Item> Columns = new List<Item>(); 
} 

public class Item 
{ 
    public string Name { get; set; } 
    public string Value { get; set; } 
} 

Но теперь вопрос, как я могу сказать DataGrid, что каждое свойство Name в списке столбцов является заголовок столбца. И каждое значение является значением строки?

Это моя XAML (ничего сложного):

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:WpfApplication1" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.DataContext> 
     <local:MainWindowViewModel x:Name="MainWindowViewModel" /> 
    </Window.DataContext> 
    <Grid> 
     <DataGrid ItemsSource="{Binding ResultTable}" 
        AutoGenerateColumns="True" /> 
    </Grid> 
</Window> 

ответ

1

ИТАК испытал это и работает на диаграмме в комментариях ниже.

Класс строки

public class Row 
{ 
    private ObservableCollection<Item> columns = new ObservableCollection<Item>(); 

    public Row(params Item[] items) 
    { 
     foreach (var item in items) 
      Columns.Add(item); 
    } 

    public ObservableCollection<Item> Columns 
    { 
     get { return columns; } 
     set { columns = value; } 
    } 
} 

Item.cs

public class Item 
{ 
    public Item(string name, string value) 
    { 
     this.Name = name; 
     this.Value = value; 
    } 
    public string Name { get; set; } 
    public string Value { get; set; }  
} 

Пользовательские DataGRidBoundColumn

public class CustomBoundColumn : DataGridBoundColumn 
{ 
    public string TemplateName { get; set; } 

    protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem) 
    { 
     var binding = new Binding(((Binding)Binding).Path.Path); 
     binding.Source = dataItem; 

     var content = new ContentControl(); 
     content.ContentTemplate = (DataTemplate)cell.FindResource(TemplateName); 
     content.SetBinding(ContentControl.ContentProperty, binding); 
     return content; 
    } 

    protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem) 
    { 
     return GenerateElement(cell, dataItem); 
    } 
} 

MainWindow.xaml.cs

public partial class MainWindow : Window 
{ 
    public ObservableCollection<Row> ResultTable 
    { 
     get; 
     set; 
    } 
    public MainWindow() 
    { 
     InitializeComponent(); 
     this.DataContext = this; 
     Loaded += (s, args) => 
      { 
       this.ResultTable = new ObservableCollection<Row>(); 
       ResultTable.Add(new Row(new Item("Name", "Peter"), new Item("Age", "21"), new Item("Sex", "Male"))); 
       ResultTable.Add(new Row(new Item("Name", "Sara"), new Item("Age", "25"), new Item("Sex", "Female"))); 
       ResultTable.Add(new Row(new Item("Name", "Mike"), new Item("Age", "28"), new Item("Sex", "Male"))); 

       var columns = ResultTable.First() 
          .Columns 
          .Select((x, i) => new { Name = x.Name, Value = x.Value, Index = i }) 
          .ToArray(); 

       foreach (var column in columns) 
       { 
        var binding = new Binding(string.Format("Columns[{0}].Value", column.Index)); 
        data.Columns.Add(new CustomBoundColumn() 
         { 
          Header = column.Name, 
          Binding = binding, 
          TemplateName = "CustomTemplate" 
         });       
       } 
       data.ItemsSource = this.ResultTable; 

      }; 
    } 
} 

и, наконец, XAML приятный и простой

<Window.Resources> 
    <DataTemplate x:Key="CustomTemplate"> 
     <Border Padding="3"> 
      <TextBlock Text="{Binding}" Foreground="Black" /> 
     </Border> 
    </DataTemplate> 
</Window.Resources> 

    <Grid> 
     <DataGrid Name="data" 
        AutoGenerateColumns="False">    
     </DataGrid> 
    </Grid>  

Это делается в коде позади, но я полагаю, вы можете настроить для ViewModel. Подробнее об исправлении можно найти Here

+0

Спасибо за ваш комментарий, я не могу создать класс, похожий на Person, потому что количество моих столбцов отличается каждый раз. Мой DataGrid используется для отображения результатов SQL-запроса ... – Rosi

+0

ok, но именно поэтому я дал вам исправление для ваших классов в верхней части ответа – SWilko

+0

Да, но с вашим решением оно выглядит следующим образом: http: // www .directupload.net/file/d/3820/dnakoqwi_png.htm Я хотел, чтобы он отображался следующим образом: http://www.directupload.net/file/d/3820/pwqqc9th_png.htm - Как динамически создавать свойства в классе и установить для них значения – Rosi

Смежные вопросы