Chr*_*s J 8 data-binding wpf datatable binding datagrid
我已经尝试了一切,无处可去,所以我希望有人可以给我一点时间.我根本无法获得绑定来成功地拉取数据网格中的数据.
我有一个DataTable,其中包含多个MyDataType列
public class MyData
{
string nameData {get;set;}
bool showData {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
MyDataType有2个属性(一个字符串,一个布尔值)我创建了一个测试DataTable
DataTable GetDummyData()
{
DataTable dt = new DataTable("Foo");
dt.Columns.Add(new DataColumn("AnotherColumn", typeof(MyData)));
dt.Rows.Add(new MyData("Row1C1", true));
dt.Rows.Add(new MyData("Row2C1", false));
dt.AcceptChanges();
return dt;
}
Run Code Online (Sandbox Code Playgroud)
我有一个WPF DataGrid,我想展示我的DataTable.但我想做的就是改变每个单元格的呈现方式,以便每个单元格显示[TextBlock] [Button],并将值绑定到MyData对象,这就是我遇到麻烦的地方.
我的XAML看起来像这样
<Window.Resources>
<ResourceDictionary>
<DataTemplate x:Key="MyDataTemplate" DataType="MyData">
<StackPanel Orientation="Horizontal" >
<Button Background="Green" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="5,0,0,0" Content="{Binding Path=nameData}"></Button>
<TextBlock Background="Green" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5,0,0,0" Text="{Binding Path=nameData}"></TextBlock>
</StackPanel>
</DataTemplate>
</ResourceDictionary>
</Window.Resources>
<Grid>
<dg:DataGrid Grid.Row="1" ItemsSource="{Binding}" AutoGenerateColumns="True"
x:Name="dataGrid1" SelectionMode="Single" CanUserAddRows="False"
CanUserSortColumns="true" CanUserDeleteRows="False" AlternatingRowBackground="AliceBlue"
AutoGeneratingColumn="dataGrid1_AutoGeneratingColumn" />
</Grid>
Run Code Online (Sandbox Code Playgroud)
现在我加载的所有内容都是尝试将DataTable绑定到WPF DataGrid
dt = GetDummyData();
dataGrid1.ItemsSource = dt.DefaultView;
Run Code Online (Sandbox Code Playgroud)
TextBlock和Button显示,但它们不绑定,这使它们留空.任何人都可以告诉我他们是否知道如何解决这个问题.这应该很简单,这正是微软引导我们相信的.我Column.CellTemplate在AutoGenerating活动期间设置了并且仍然没有绑定.
请帮忙!!!
Jos*_*ant 16
编辑:更新以反映Aran Mulholland的输入(请参阅注释)
显然,DataGrid正在将整个传递DataRowView到每个单元格.这就是绑定不起作用的原因.你DataTemplate期望它是DataContext类型MyData,但它是类型DataRowView.我提出的(有点hack-ish)解决方法来获得DataContext你想要的是创建一个自定义DataGridTemplateColumn,将从中提取必要的项目DataRowView.代码如下:
<Window x:Class="DataGridTemplateColumnSample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dg="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<ResourceDictionary>
<DataTemplate x:Key="MyDataTemplate" DataType="DataRowView">
<StackPanel Orientation="Horizontal">
<Button Background="Green" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="5,0,0,0" Content="{Binding Path=nameData}"></Button>
<TextBlock Background="Green" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5,0,0,0" Text="{Binding Path=nameData}"></TextBlock>
</StackPanel>
</DataTemplate>
</ResourceDictionary>
</Window.Resources>
<Grid>
<dg:DataGrid Grid.Row="1" AutoGenerateColumns="True" x:Name="dataGrid1" SelectionMode="Single"
CanUserAddRows="False" CanUserSortColumns="true" CanUserDeleteRows="False"
AlternatingRowBackground="AliceBlue" AutoGeneratingColumn="dataGrid1_AutoGeneratingColumn"
ItemsSource="{Binding}" VirtualizingStackPanel.VirtualizationMode="Standard" />
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
using System.Data;
using System.Windows;
using Microsoft.Windows.Controls;
namespace DataGridTemplateColumnSample
{
public partial class Window1
{
public Window1()
{
InitializeComponent();
DataContext = GetDummyData().DefaultView;
}
private static DataTable GetDummyData()
{
var dt = new DataTable("Foo");
dt.Columns.Add(new DataColumn("OneColumn", typeof(MyData)));
dt.Columns.Add(new DataColumn("AnotherColumn", typeof(MyData)));
dt.Rows.Add(new MyData("Row1C1", true), new MyData("Row1C2", true));
dt.Rows.Add(new MyData("Row2C1", false), new MyData("Row2C2", true));
dt.AcceptChanges();
return dt;
}
private void dataGrid1_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
var column = new DataRowColumn(e.PropertyName);
column.Header = e.Column.Header;
column.CellTemplate = (DataTemplate)Resources["MyDataTemplate"];
e.Column = column;
}
}
public class DataRowColumn : DataGridTemplateColumn
{
public DataRowColumn(string column) { ColumnName = column; }
public string ColumnName { get; private set; }
protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
{
var row = (DataRowView) dataItem;
var item = row[ColumnName];
cell.DataContext = item;
var element = base.GenerateElement(cell, item);
return element;
}
}
public class MyData
{
public MyData(string name, bool data) { nameData = name; showData = data; }
public string nameData { get; set; }
public bool showData { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
注意:此方法似乎仅适用于容器虚拟化关闭或标准模式.如果VirtualizationMode设置为Recycling,则不应用模板.
小智 8
找到这个线程并且在这里显示的代码有问题之后,我在MSDN上遇到了这个线程,它运行得更好!到目前为止,我没有看到任何虚拟化问题.
http://social.msdn.microsoft.com/Forums/en/wpf/thread/8b2e94b7-3c44-4642-8acc-851de5285062
码:
private void dataGrid1_AutoGeneratingColumn(object sender, Microsoft.Windows.Controls.DataGridAutoGeneratingColumnEventArgs e)
{
if (e.PropertyType == typeof(MyData))
{
MyDataGridTemplateColumn col = new MyDataGridTemplateColumn();
col.ColumnName = e.PropertyName; // so it knows from which column to get MyData
col.CellTemplate = (DataTemplate)FindResource("MyDataTemplate");
e.Column = col;
e.Column.Header = e.PropertyName;
}
}
public class MyDataGridTemplateColumn : DataGridTemplateColumn
{
public string ColumnName
{
get;
set;
}
protected override System.Windows.FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
{
// The DataGridTemplateColumn uses ContentPresenter with your DataTemplate.
ContentPresenter cp = (ContentPresenter)base.GenerateElement(cell, dataItem);
// Reset the Binding to the specific column. The default binding is to the DataRowView.
BindingOperations.SetBinding(cp, ContentPresenter.ContentProperty, new Binding(this.ColumnName));
return cp;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
35382 次 |
| 最近记录: |