我在一个类中创建了一个索引属性,我需要为 DataGrid
中 DataGridTemplateColumn
的每个单元格设置绑定(bind)(每个单元格与其相应的项索引属性)。
它用于工作计划生成应用程序。网格中的每个单元格都将显示与员工和轮类相关的数据——轮类中的更多员工将向右扩展网格,即添加更多列。网格显示以编程方式创建和填充的数据结构,并且未绑定(bind)到数据库表。为了在本论坛中更轻松地进行演示和代码检查,我已将所有内容简化为基本要素。
这是一张图片:
这显然是错误的,因为我无法正确设置绑定(bind)。我可以将 StackPanel 中的字段绑定(bind)到索引属性的第一个(或任何其他)项,但不能绑定(bind)到索引/参数化设置中。
这是我的 xaml(部分):
<Grid HorizontalAlignment="Left">
<DataGrid x:Name="grdSch" HorizontalAlignment="Left" Height="400" VerticalAlignment="Top" Margin="8,0,0,0" AutoGenerateColumns="False" SelectionUnit="Cell"/>
</Grid>
<Page.Resources>
<DataTemplate x:Key="SPI_Template">
<StackPanel>
<TextBlock Text="{Binding Path=shftDate}"/>
<TextBlock Text="{Binding Path=shftKind}"/>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="SEI_Template">
<StackPanel>
<TextBlock Text="{Binding Path=data[0].emplName}"/>
<TextBlock Text="{Binding Path=data[0].shftTime}"/>
</StackPanel>
</DataTemplate>
</Page.Resources>
以及生成列的代码:
private void Page_Loaded(object sender, RoutedEventArgs e)
{
// Create the grid columns
DataGridTemplateColumn col = new DataGridTemplateColumn();
col.Header = "Shift";
col.CellTemplate = (DataTemplate)FindResource("SPI_Template");
grdSch.Columns.Add(col);
for (int i = 0; i < 30; i++)
{
col = new DataGridTemplateColumn();
col.Header = "Employee " + (i + 1);
col.Width = 100;
col.CellTemplate = (DataTemplate)FindResource("SEI_Template");
// for now show only the 5 first elements
col.Visibility = i >= 5 ? Visibility.Hidden : Visibility.Visible;
grdSch.Columns.Add(col);
}
}
data[]
属性被索引。现在的绑定(bind)(例如 "{Binding Path=data[0].emplName}"
)适用于属性的第一项。如果我将其更改为 "{Binding Path=data[1].emplName}"
它将绑定(bind)到第二个,依此类推。但这当然不是我需要的。有什么方法可以将绑定(bind)更改为..."{Binding Path=data[Grid.ColumnIndex-1].emplName}"
?搜索并找到了一些关于“参数化绑定(bind)”等的帖子,但找不到非常明显或直接的内容。当然,我可以采取愚蠢的方式并在 xaml 中添加 30 个类似的模板(仅在索引属性的索引中有所不同)- 这肯定会起作用,但我正在研究以更好的方式进行制作。
有人可以帮忙吗?
提前致谢
最佳答案
一种解决方案是创建自定义列类型(派生自 DataGridTemplateColumn
),它公开一个额外的 Binding
属性,我们将使用它来绑定(bind)单元格内容。这是列代码:
public class DataGridBoundColumn : DataGridTemplateColumn
{
public BindingBase Binding { get; set; }
protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
{
var element = base.GenerateEditingElement(cell, dataItem);
if (element != null && Binding != null)
element.SetBinding(ContentPresenter.ContentProperty, Binding);
return element;
}
protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
{
var element = base.GenerateElement(cell, dataItem);
if (element != null && Binding != null)
element.SetBinding(ContentPresenter.ContentProperty, Binding);
return element;
}
}
然后我们需要稍微修改列生成代码:
private void Page_Loaded(object sender, RoutedEventArgs e)
{
var col = new DataGridTemplateColumn
{
Header = "Shift",
CellTemplate = (DataTemplate)FindResource("SPI_Template")
};
grdSch.Columns.Add(col);
for (int i = 0; i < 30; i++)
{
col = new DataGridBoundColumn
{
Header = "Employee " + (i + 1),
Binding = new Binding($"data[{i}]"),
Width = 100,
CellTemplate = (DataTemplate)FindResource("SEI_Template"),
};
grdSch.Columns.Add(col);
}
}
最后,由于我们生成的列已经显示data[i]
,我们需要相应地修改SEI_Template
:
<DataTemplate x:Key="SEI_Template">
<StackPanel>
<TextBlock Text="{Binding emplName}" />
<TextBlock Text="{Binding shftDate}" />
</StackPanel>
</DataTemplate>
关于c# - 将 DataGrid 单元格绑定(bind)到索引属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47187850/