views:

1325

answers:

3

I have found that datagrid columns can be dynamically created and bound in Silverlight. However I can't find a way to bind data to those columns.

If I try to bind any type of object with AutoGenerateColumns = true, then the names of each property of the object get added as columns and the object information is displayed in the grid in addition to the existing columns which show no data.

If I apply a list with AutoGenerateColumns = false, then i still get rows to show up in the table but no data in the columns.

I do not want to create a specific object for each case that i need to display data in the datagird.

I do not want to have my column names limited to the names of properties, e.g. names with out spaces.

I want to be able to bind a list or a dictionary array to the data grid. I also want to be able to control what data shows up in what columns.

+1  A: 

You're probably almost there but just have something subtly wrong in your xaml, here's a working example:

<UserControl x:Class="Testproject.EditableDataGrid"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <data:DataGrid x:Name="myDataGrid" AutoGenerateColumns="False"> 
            <data:DataGrid.Columns>
                <data:DataGridTextColumn Header="My text" Binding="{Binding StringValue}" />
                <data:DataGridCheckBoxColumn Header="Check Box" Binding="{Binding IsChecked}" />
                <data:DataGridTemplateColumn Header="A template column">
                    <data:DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <Rectangle Width="20" Height="5" Fill="Red"/>
                            <TextBlock Text="{Binding IntValue}" />
                        </StackPanel>
                    </DataTemplate>
                </data:DataGridTemplateColumn.CellTemplate>

            </data:DataGridTemplateColumn>
                <data:DataGridTextColumn Header="My int" Binding="{Binding IntValue}" />
            </data:DataGrid.Columns>
        </data:DataGrid>
    </Grid>
</UserControl>

using System.Windows;
using System.Windows.Controls;
using System.Collections.Generic;

namespace Testproject
{
    public partial class EditableDataGrid   :UserControl
    {
        public EditableDataGrid()
        {
            InitializeComponent();

            myDataGrid.ItemsSource = new List<ClassForDataGridTest>()
                            {
                                new ClassForDataGridTest() {StringValue="hello", IntValue=21, IsChecked=false}
                                , new ClassForDataGridTest() {StringValue="the second", IntValue=122, IsChecked = true}
                            };
        }
    }

    public class ClassForDataGridTest   : DependencyObject
    {

        public string StringValue {get; set;}

        public int IntValue {get; set;}

        public bool IsChecked { get; set; }

    }
}
mattmanser
+1  A: 

Assume you have a class or some other container that you want to bind information to, you can do the following.

DataGridTextColumn product = new DataGridTextColumn();
                product.Binding = new System.Windows.Data.Binding("Product");
                product.Header = "Product";

                DataGridTextColumn date = new DataGridTextColumn();
                date.Binding = new System.Windows.Data.Binding("Date");
                date.Header = "Date";

                DataGridTextColumn version = new DataGridTextColumn();
                version.Binding = new System.Windows.Data.Binding("FileVersion");
                version.Header = "Version";

                DataGridTextColumn timestamp = new DataGridTextColumn();
                timestamp.Header = "TimeStamp";
                timestamp.Binding = new System.Windows.Data.Binding("TimeStamp");

                DataGridTextColumn user = new DataGridTextColumn();
                user.Header = "User";
                user.Binding = new System.Windows.Data.Binding("User");

                rpdata.Columns.Add(product);
                rpdata.Columns.Add(date);
                rpdata.Columns.Add(version);
                rpdata.Columns.Add(timestamp);
                rpdata.Columns.Add(user);

Now just set your itemsource of the datagrid to the collection of items you have.

This allows you to set the header you want to display, and it also binds the information to variables in the container, thus it displays the information of only the columns you add.

Johannes
A: 

really great... thanks dude

krishna
If its a favorite, click the star on the question and you'll have it bookmarked in your profile for quick reference.
JustSmith