c# - 将 DataGrid 单元格绑定(bind)到索引属性

标签 c# wpf xaml data-binding datagrid

我在一个类中创建了一个索引属性,我需要为 DataGridDataGridTemplateColumn 的每个单元格设置绑定(bind)(每个单元格与其相应的项索引属性)。

它用于工作计划生成应用程序。网格中的每个单元格都将显示与员工和轮类相关的数据——轮类中的更多员工将向右扩展网格,即添加更多列。网格显示以编程方式创建和填充的数据结构,并且未绑定(bind)到数据库表。为了在本论坛中更轻松地进行演示和代码检查,我已将所有内容简化为基本要素。

这是一张图片:

enter image description here

这显然是错误的,因为我无法正确设置绑定(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/

相关文章:

c# - Visual Studio 找不到文件 - 调试

c# - 将 DataRow Item 转换为 Int C# 时出错

wpf - MVVM - 如何显示 View ?

c# - 使 CollectionViewSource 无效

c# - 如何在 Windows 8 中创建大于屏幕的 View

c# - 如何将带有绘图的 Canvas 放置在 ListView 控件的特定列内?

c# - 从另一个 View 返回数据 Xamarin.iOS

c# - 如何获得 EnvDte.ActiveDocument 的 IWpfTextView?

wpf - 如何创建包含具有公共(public)父类(super class)的对象的 F# 列表?

wpf - 如何基于 2 个或更多 WPF 文本框填充 WPF 标签?