如何使用MVVM将ItemSource设置为DataTable来为DataGrid设置模板

时间:2015-09-20 11:01:02

标签: c# wpf mvvm

我的XAML:

<DataGrid Grid.Row="1" ItemsSource="{Binding PersonTable}" CanUserAddRows="False" CanUserDeleteRows="False"/>

我在ViewModel中的代码:

PersonTable = new DataTable();
PersonTable.Columns.Add("Name");
PersonTable.Columns.Add("Delete");

我想在AccessType列中获取Button,但是:

DataRow dataRow = PersonTable.NewRow();
dataRow["Name"] = person.Name;
dataRow["Delete"] = new Button();
PersonTable.Rows.Add(dataRow);

使用'System.Windows.Controls.Button'值创建单元格。我想实现与使用此xaml相同的行为:

<DataGridTemplateColumn Header="Delete">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Button/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

使用DataTable时如何使用模板?如何绑定例如。在DataGrid中以人为单位的颜色?

编辑: 删除列就是一个例子。我事先不知道列名和列数。

EDIT2: 由于误解:删除只是一个例子,我需要在运行时20列或更多列。我需要能够在单元格中放置按钮并绑定到属性。

2 个答案:

答案 0 :(得分:0)

一个干净利落的方法是

   <DataGrid ItemsSource="{Binding PersonTable}" 
      AutoGenerateColumns="False" 
      CanUserAddRows="False" Grid.Row="1" >
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Name}"
                                Width="*"/>
            <DataGridTemplateColumn Width="Auto" Header="Delete">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Button Content="Delete"
                                Command="{Binding SomeCommand,
                            RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
                                CommandParameter="{Binding}"
                                Margin="5"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>       

您可以将命令绑定到删除按钮并执行操作。

答案 1 :(得分:-2)

您的DataGrid:

<DataGrid x:Name="MyDataGrid1" HorizontalAlignment="Left" Margin="89,34,0,0" VerticalAlignment="Top" AutoGenerateColumns="False">
            <DataGrid.Columns>
            </DataGrid.Columns>
        </DataGrid>

现在,我们将使用XAML的动态加载。为此,我们需要在单独的文本文件中进行标记。将其构建操作更改为内容,并将“复制到OutputDirectory”更改为“始终”。

myDataGridCol.txt:

<DataGridTemplateColumn 
                    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    Width="100">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ToggleButton Content="{Binding ^colname^}" Background="Red">
                            </ToggleButton>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

动态地向DataGrid添加列可以这样完成:

foreach (DataColumn col in PersonTable.Columns)
            {
                DataGridTemplateColumn dtcol;

                using (StreamReader reader = new StreamReader(("32678595/DataGridTemplateColumn.txt")))
                {
                    String xamlContent = reader.ReadToEnd();
                    xamlContent = xamlContent.Replace("^colname^", col.ColumnName);

                    dtcol = (DataGridTemplateColumn)(System.Windows.Markup.XamlReader.Parse(xamlContent));
                }

                dtcol.Header = col.ColumnName;
                MyDataGrid1.Columns.Add(dtcol);
            }

            MyDataGrid1.ItemsSource = PersonTable.DefaultView;

可以使用以下概念完成对单元格的绑定:

<DataGridTemplateColumn Width="100" Header="Color">
    <DataGridTemplateColumn.CellTemplate>
         <DataTemplate>
           <Label>
             <Label.Background>
               <SolidColorBrush x:Name="CellColor" Color="{Binding PropertyColor}"/>
             </Label.Background>
           </Label>
         </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

现在,您知道如何动态添加列并绑定背景属性。您可以相应地制作ViewModel。

您可以使用Color col = (Color)ColorConverter.ConvertFromString(value);将字符串转换为颜色以便于绑定。

如果您使用String来存储颜色值,那么正常绑定就可以了。

<Button Content="color" Background="{Binding PropertyColor}"/>