Silverlight Datagrid:将自定义ContentControl绑定到单元格

时间:2014-04-30 16:35:49

标签: wpf silverlight wpfdatagrid

首先,我对WPF和数据绑定并不熟悉,但我在网上搜索了一个解决方案并没有找到解决方案。

我有自定义内容控件,应该在Datagrid-Cell中显示。由于我没有控件的源代码,因此我无法对其进行修改以解决我的问题。

Datagrid包含(至少)2列,一列是行名,另一列是自定义控件。为了完成工作,我以编程方式为自定义控件创建了自定义CustomDataGridColumn,同时在XAML中定义了第一列和基本数据网格

XAML(删除了不必要的东西):

       <sdk:DataGrid Grid.Row="1" Name="dg" CanUserReorderColumns="False"
                     CanUserSortColumns="False" AutoGenerateColumns="False"
                     FrozenColumnCount="1" VerticalScrollBarVisibility="Auto" 
           HorizontalScrollBarVisibility="Auto"   
           HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
           VirtualizingStackPanel.VirtualizationMode="Standard" >
           <sdk:DataGrid.Columns>
               <sdk:DataGridTemplateColumn Header="Model" IsReadOnly="True">
                   <sdk:DataGridTemplateColumn.CellTemplate>
                       <DataTemplate>
                           <TextBlock Text="{Binding Model}"
                       </DataTemplate>
                   </sdk:DataGridTemplateColumn.CellTemplate>
               </sdk:DataGridTemplateColumn>
           </sdk:DataGrid.Columns>
       </sdk:DataGrid>

CustomDataGridColumn:

public class CustomDataGridColumn : DataGridColumn
{
    int col { get; set; }
    public CustomDataGridColumn (int pCol, string header)
        : base()
    {
        col = pCol;
        IsReadOnly = true;
        Header = header;

    }

    protected override object PrepareCellForEdit(FrameworkElement editingElement, RoutedEventArgs editingEventArgs)
    {
        //since editing cells is prohibited we return the editing element right back
        return editingElement;
    }

    protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
    {
        //since editing cells is prohibited we return the editing cell right back
        return cell;
    }

    protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
    {
        TableRowObject element = dataItem as TableRowObject;
        if (element == null )
        {
            return cell;
        }

        return element.customControls[col];
    }
}

我在一个&#39; ObservableObjectCollection&#39;中使用的TableRowObject。作为dg.itemSource:

public class TableRowObject
{
    public string Model { get; set; }
    public CustomComponent[] customComponents { get; set; }
}

除非你滚动数据网格,否则它的效果非常好:一旦虚拟化命中,连续的customControl就不适合模型列(事实上,滚动出视口的最后一个单元格得到了无需修改即可重复使用)。调试时会调用列的GenerateElement方法,但看起来似乎是错误的元素。

我尝试了什么:

  • 在XAML中使用VirtualizationStackPanel.VirtualizationMode="Standard VirtualizingStackPanel.IsVirtualizing="False"禁用虚拟化会因为IsVirtualizing而导致XAML解析异常只读(?!)
  • 在Datagrid周围使用Scrollviewer来禁用虚拟化,工作正常,但我松开了datagrid的冻结字符数
  • 我尝试使用自定义列的绑定,该列应显示与第一列中相同的字符串 - 仍然是虚拟化问题,如下所示:

    绑定b =新绑定(&#34;模型&#34;);  binding source = element;  TextBlock tb = new TextBlock();  tb.setBinding(TextBlock.textProperty,b);

之后,我假设我使用自定义列GenerateElement或至少绑定时出错。另外,如果我必须使用绑定,我需要一个自定义控件可以绑定的空容器?

很高兴获得任何帮助以禁用虚拟化(不会丢失冻结列)或建议如何将自定义控件绑定到列。

提前致谢

1 个答案:

答案 0 :(得分:0)

似乎Silverlight DataGrid无法设置另一个ItemsPanelTemplate(就像Listbox那样)。

但我想知道你为什么要在自己的Column实现中进行“自定义单元格处理”。 您可以动态/以编程方式将TemplateColumns添加到DataGrid的Columns集合中。 所以当你写这个xaml:

<Resources>
    <DataTemplate x:Key="CustomTemplate">
        <CustomContentControl Content="{Binding Path=FooDetails}"/>
    </DataTemplate>
</Resources>

<sdk:DataGrid.Columns>
    <sdk:DataGridTemplateColumn Header="Foo"
              IsReadOnly="True"
              CellTemplate="{StaticResource CustomTemplate}"/>
</sdk:DataGrid.Columns>

你可以改为编写你的代码隐藏:

private void AddColumn()
{
    var colDef = new DataGridTemplateColumn(){Header = "Foo", IsReadOnly = True};
    colDef.CellTemplate = (DataTemplate) this.Resources["CustomTemplate"];
    myGrid.Columns.Add( colDef );
}