开发者

Adding new columns at runtime

开发者 https://www.devze.com 2023-03-26 16:41 出处:网络
I am w开发者_高级运维orking in Silverlight MVVM pattern, there is a datagrid (component one) which initially will be having 4 columns, later at runtime user will be displayed list of columns in combob

I am w开发者_高级运维orking in Silverlight MVVM pattern, there is a datagrid (component one) which initially will be having 4 columns, later at runtime user will be displayed list of columns in combobox, he can select the columns he want to see in the datagrid and click a button to add the columns in datagrid, so at runtime i have to add the Column in the datagrid. Is it possible using the Silverlight MVVM pattern. Please help.


Sure it's possible. You'll define the data grid and binding in your xaml, then you'll have to do data binding and add the columns in code. Be sure and turn autoGenerateColumns off. I keep a separate list that describes my columns. I also define the column template in code, since I want tooltip and headers different for each column. Here is an example that adds either a float or integer column, you can add other types if you need to :

First define the grid - I don't think it matters that you're using a component one datagrid

            <!-- NOTE: Creating columns is done Programmatically -->
            <sdk:DataGrid x:Name="DataGridForDistrictSummaries" Grid.Column="1" 
                              AutoGenerateColumns="False" 
                              VerticalScrollBarVisibility="Visible"  
                              HorizontalScrollBarVisibility="Visible" 
                              HorizontalAlignment="Stretch" 
                              VerticalAlignment="Stretch" 
                              MinHeight="70"
                              ItemsSource="{Binding dataGridView}"
                              AlternatingRowBackground="LightBlue"
                        >
           </sdk:DataGrid>

Then you need to build your grid columns, I rebuild the entire grid:

    public static void BuildDataGridColumns(DataGrid dataGrid, List<DataGridColumnDescription> columnDescriptionList)
    {
        // clear out the old columns and re-build them with new criteria
        dataGrid.Columns.Clear();

        // add columns based on the description
        int index = 0;
        foreach (DataGridColumnDescription column in columnDescriptionList)
        {
            if (DataGridColumnDescriptionValueType.floatDataType == column.valueType)
            {
                dataGrid.Columns.Add(DataGridColumnBuilder.CreateFloatColumn(index++, column.name, column.header, column.description));
            }
            else
            {
                dataGrid.Columns.Add(DataGridColumnBuilder.CreateIntColumn(index++, column.name, column.header, column.description));
            }
        }
    }

This lets you have different data types in your grid. That is important for controlling how you want to display the data. In this case, I wanted 2 decimal points to display

    public static DataGridTextColumn CreateFloatColumn(int index, string fieldName, string header, string description)
    {
        DataGridTextColumn column = new DataGridTextColumn();
        column.Header = header;
        column.HeaderStyle = BuildColumnHeaderStyle(description);
        column.Binding = new Binding("floatValuesList[" + index + "]");
        column.Binding.StringFormat = "0.00";
        column.CellStyle = BuildFloatCellStyle(fieldName, description);
        return column;
    }

    public static DataGridTextColumn CreateIntColumn(int index, string fieldName, string header, string description)
    {
        DataGridTextColumn column = new DataGridTextColumn();
        column.Header = header;
        column.HeaderStyle = BuildColumnHeaderStyle(description);
        column.Binding = new Binding("intValuesList[" + index + "]");
        column.CellStyle = BuildCellStyle(fieldName, description);
        return column;
    }

This defines a style in code, I've hard coded some things - but you can make it as dynamic as you need:

    private static Style BuildColumnHeaderStyle(string tooltip)
    {
        FontWeight fw = FontWeights.Bold;
        Style newGridHeaderStyle = new Style(typeof(DataGridColumnHeader));
        newGridHeaderStyle.Setters.Add(new Setter { Property = DataGridColumnHeader.FontSizeProperty, Value = 9.0 });
        newGridHeaderStyle.Setters.Add(new Setter { Property = DataGridColumnHeader.FontWeightProperty, Value = FontWeights.Bold });
        newGridHeaderStyle.Setters.Add(new Setter { Property = DataGridColumnHeader.ContentTemplateProperty, Value = CreateDataGridColumnHeaderTemplate(tooltip) });
        return newGridHeaderStyle;
    }

    private static Style BuildFloatCellStyle(string fieldName, string tooltip)
    {
        Style newGridCellStyle = new Style(typeof(DataGridCell));
        newGridCellStyle.Setters.Add(new Setter { Property = DataGridCell.FontSizeProperty, Value = 11.0 });
        newGridCellStyle.Setters.Add(new Setter { Property = DataGridCell.HorizontalContentAlignmentProperty, Value = HorizontalAlignment.Right });
        return newGridCellStyle;
    }

    private static Style BuildCellStyle(string fieldName, string tooltip)
    {
        Style newGridCellStyle = new Style(typeof(DataGridCell));
        newGridCellStyle.Setters.Add(new Setter { Property = DataGridCell.FontSizeProperty, Value = 11.0 });
        newGridCellStyle.Setters.Add(new Setter { Property = DataGridCell.HorizontalContentAlignmentProperty, Value = HorizontalAlignment.Right });


        return newGridCellStyle;
    }

You have to create the cell template in code as well. This creates the xaml text string and uses a XamlReader to load it

    private static DataTemplate CreateDataGridColumnHeaderTemplate(string tooltip)
    {
        string str = @"<DataTemplate xmlns='http://schemas.microsoft.com/client/2007'>"
                    + @"<ContentControl   Content='{Binding}'>"
                    + @"<ToolTipService.ToolTip>"
                    + @"<ToolTip Content='" + tooltip + "'>"
                    + @"</ToolTip>"
                    + @"</ToolTipService.ToolTip>"
                    + @"</ContentControl >"
                    + @"</DataTemplate>";
        return (DataTemplate)XamlReader.Load(str);
    }


Refer link: http://blogs.msdn.com/b/scmorris/archive/2008/04/14/defining-silverlight-datagrid-columns-at-runtime.aspx

Code snippet is from above link:(this is one way of doing that.Otherway is also explained in that link)

Xaml:

<UserControl.Resources>
<local:DateTimeConverter x:Key="DateConverter" />

<DataTemplate x:Key="myCellTemplate">
    <TextBlock 
        Text="{Binding Birthday, 
        Converter={StaticResource DateConverter}}" 
        Margin="4"/>
</DataTemplate>

<DataTemplate x:Key="myCellEditingTemplate">
    <basics:DatePicker 
        SelectedDate="{Binding Birthday, Mode=TwoWay}" />
</DataTemplate>

Code Behind:

DataGridTemplateColumn templateColumn = new DataGridTemplateColumn();
templateColumn.Header = "Birthday";
templateColumn.CellTemplate = (DataTemplate)Resources["myCellTemplate"];
templateColumn.CellEditingTemplate = 
                   (DataTemplate)Resources["myCellEditingTemplate"];
targetDataGrid.Columns.Add(templateColumn);
0

精彩评论

暂无评论...
验证码 换一张
取 消