【问题标题】:How to programmatically hide cells of a DataGrid in wpf c#?如何在 wpf c# 中以编程方式隐藏 DataGrid 的单元格?
【发布时间】:2017-01-26 13:01:38
【问题描述】:

有没有办法在代码隐藏中隐藏/折叠特定的 dataGrid 单元格?由于我的数据表列是在运行时创建的,因此我无法指定属性(在 XAML 中)来正确设置这些数据触发器、模板选择器等。 但是,我能够通过循环遍历数据表以将行/列索引添加到列表(如下)来定位我想要折叠的确切单元格。

我知道这是非正统的,但我已经阅读了几个星期试图解决这个问题的线程,但没有任何东西让我到达那里。这似乎是最简单的解决方案(如果可能的话)。

private static List<KeyValuePair<int, int>> GetCellsToHide(DataTable pivotTable)
{
    var noCellValueList = new List<KeyValuePair<int, int>>();
    foreach (DataRow row in pivotTable.Rows)
    {
        foreach (DataColumn col in pivotTable.Columns)
        {
            if (row[col].ToString() == "HideMe")
            {
                int rowIndex = pivotTable.Rows.IndexOf(row);
                int colIndex = pivotTable.Columns.IndexOf(col);

                noCellValueList.Add(new KeyValuePair<int, int>(rowIndex, colIndex));

            }
        }
    }

    return noCellValueList;
}

编辑:数据模板和转换器信息

我目前正在通过自动生成列来构建数据网格。我知道所有其他列的名称,因此我可以缩小到动态生成的列。我的动态列是 DataTemplate5,例如(下面的简化版本):

private void DataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    if (e.Column.Header.ToString() == "Name")
        e.Column.Header = "File Name";

    else
    {
        string origHeader = e.Column.Header.ToString();

        DataGridTemplateColumn templateColumn = new DataGridTemplateColumn    //create new template column
        {
             Header = origHeader,
             CellTemplate = (DataTemplate)Resources["DataTemplate5"]

        }; 

        e.Column = templateColumn; // Replace the auto-generated column with the templateColumn.    
    }
}

但是由于我没有要绑定的属性(列)名称,所以我无法正确绑定它。这是我通过数据模板和 ivalueconverter 隐藏单元格的最新尝试:

<DataTemplate x:Key="DataTemplate5">
    <DataTemplate.Resources>
        <local:StringToVisibilityConvertor x:Key="VisibilityConvertor" />
    </DataTemplate.Resources>
    <StackPanel Visibility="{Binding BindsDirectlyToSource=True, Converter={StaticResource VisibilityConvertor}}">
        <Button Name="Button1" Click="ButtonClick">
            <Button.Style>
                <Style  TargetType="Button">
                    <Style.Setters>
                        <Setter Property="Background" Value="Orange"/>
                    </Style.Setters>
                </Style>
            </Button.Style>
        </Button>
    </StackPanel>
</DataTemplate>

还有转换器:

public class StringToVisibilityConvertor : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value.ToString() != "HideMe")
            return Visibility.Visible;
        return Visibility.Collapsed;
    }

【问题讨论】:

  • 只是想清楚一点-您是在谈论隐藏整列,对吗?您的问题是这样说的,但是您的解释似乎是在谈论单个细胞。如果你在谈论细胞,当细胞被隐藏时,你希望会发生什么?如果您在谈论列,您是否尝试过将 DataColumn 的可见性设置为 Collapsed?
  • 抱歉我已经编辑了标题。我的意思是隐藏特定的单元格,而不是整个列。
  • 我的数据表由大量的链接组成。我的数据网格将它们显示为打开链接的按钮。尽管许多单元格具有空值,但它们仍显示为按钮,并且是数据的不良表示。我需要这些单元格是空白的,并且只在有要打开的链接的单元格中显示按钮。
  • 我认为真的需要查看构建 DataGrid 的代码 - 您使用的是哪种列?这听起来像 DataTemplate 列,但你的模板定义中有什么?
  • 感谢 Ian,在上面添加了更多信息。

标签: c# wpf xaml datatable datagrid


【解决方案1】:

由于动态列,我无法让我的绑定工作。最后,我偶然发现了 Paul Stovell 的一篇很棒的文章,关于如何使用列索引作为绑定路径来创建网格。完成此操作后,我为所有列创建了一个数据模板,并使用 datatrigger 隐藏了单元格:

http://paulstovell.com/blog/dynamic-datagrid

【讨论】:

    【解决方案2】:

    必须承认,我在调整列的自动生成方面从未走得这么远 - 我很少使用自动生成的列,尽管我猜你必须这样做,因为直到运行时你才知道列。

    如果是我,我会这样调整模板:

    <DataTemplate x:Key="DataTemplate5">
        <Button Name="Button1" Click="ButtonClick" Background="Orange" Content="{Binding ???}" >
        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding ???}" Value="HideMe">
                <Setter Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
        </DataTemplate.Triggers>
    </DataTemplate>
    

    节省了对转换器的需求。不过现在的问题是为 ??? 放什么。什么都不做 - 即 {Binding}。

    您可能还需要在后面的代码中添加一些内容:

                     DataGridTemplateColumn templateColumn = new DataGridTemplateColumn    //create new template column
                     {
                         Header = origHeader,
                         CellTemplate = (DataTemplate)Resources["DataTemplate5"],
                         SortMemberPath = e.Column.SortMemberPath
                     };  
    

    实际上,先尝试一下 - 可能就足够了,同时在您的值转换器中进行一些调试。

    【讨论】:

    • 谢谢伊恩。我确实听从了您的建议并摆脱了转换器。不幸的是,仍然无法使绑定正常工作。我发布了一个答案,让我得到了我需要的东西,尽管这种方法确实有它的缺点。
    • 很高兴你得到了它 - 猜你可以将你的答案标记为答案,除非你想详细说明以供将来参考。
    • 当然。我标记了答案(上图)并提供了文章超链接。
    • 的意思是添加...我所做的基本上是获取我的数据表并将其转换为可观察的集合。处理大问号-bindings-的是他的“CustomBoundColumn”,它在代码隐藏中设置绑定。我仍然只是部分理解他的代码,否则我会详细说明,但我永远不会自己弄清楚,并且会将任何感兴趣的人指向该网站!
    • 感谢提醒,打勾。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-11
    • 1970-01-01
    • 1970-01-01
    • 2010-12-10
    • 1970-01-01
    相关资源
    最近更新 更多