C# 绑定到Datagrid';s ItemsSource集合属性而不是单个项

C# 绑定到Datagrid';s ItemsSource集合属性而不是单个项,c#,binding,silverlight-4.0,collections,datagrid,C#,Binding,Silverlight 4.0,Collections,Datagrid,在尝试绑定集合中的某些属性而不是元素的属性时,我感到困惑。 我甚至不知道如何正确表达。。。代码可能解释得更好:以下是类型(不是实际的代码,我已经将其缩短为基本代码): 公共类myType { 公共int P{get;set;} } 公共类myTypeCollection:ObservableCollection { public int Ptotal{get{返回this.Items.Select(i=>i.P).Aggregate((c,t=>t=t+c);} public int Pmin{

在尝试绑定集合中的某些属性而不是元素的属性时,我感到困惑。 我甚至不知道如何正确表达。。。代码可能解释得更好:以下是类型(不是实际的代码,我已经将其缩短为基本代码):

公共类myType
{
公共int P{get;set;}
}
公共类myTypeCollection:ObservableCollection
{
public int Ptotal{get{返回this.Items.Select(i=>i.P).Aggregate((c,t=>t=t+c);}
public int Pmin{get{this.Items.Min(i=>i.P);}}//concept
public int Pmax{get{this.Items.Max(i=>i.P);}}//concept
}
它们在模板控件中使用,其XAML如下所示: (添加注释以尽可能清楚地说明)


{Binding p}
按预期工作,因为
p
是项的属性,但如何访问集合的属性,如
Ptotal
Pmin


感谢您抽出时间阅读此文章。如果缺少任何信息,只需指出它,我会发布它。

因此您需要集合对象作为绑定源

您需要这些:

类似于此(未经测试):


我认为问题在于DataGrid绑定到集合,每一行绑定到单个项,而不是集合。您需要获得链上一级的访问权限(返回到集合本身)

如果您正在运行Silverlight 4+,则可以使用相对资源。例如:

<TextBlock Text="{Binding Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType=sdk:DataGrid, AncestorLevel=1}, Path=DataContext.Count}"

结果表明,客户改变了对网格标题的想法,他不想在标题中再显示total

顺便说一句,我一定试过20种不同的方法,包括在各种类型的转换器上打补丁,但我没能完成这项任务,不像看起来那么简单


再次感谢您提出的有趣建议。

重新标记以澄清Silverlight 4
AncestorType
AncestorLevel
似乎不存在于类型
RelativeSource
上,不幸的是,原样的代码无法编译。我认为这只适用于Silverlight 5,您可以升级您的项目吗?不幸的是,客户不想更新运行时,因为谁知道为什么。无论如何,谢谢你的建议,我会把它保存在我自己的小片段回购协议中,以备将来参考。谢谢。我正在尝试“另一种方法”,看起来恰到好处。代码今天不想遵守:elementName方法解决了异常,但textblock仍然为空。我要再调整一下。为了澄清,
myGridObject
是“主”应用程序中模板控件的名称在调试应用程序时检查VS输出窗口中的绑定异常。有任何绑定异常吗?我刚刚尝试了您的第一种方法,VisualStudio抱怨有关
AncestorType
,就像它对另一个答案的建议所做的一样。我正在考虑抛球,组成一组依赖属性来独立处理标题…你使用什么版本的silverlight?版本4中不存在RelativeSource。但是您应该对ElementName解决方案没有意见。绑定路径可能不正确。调试时,您应该在输出中看到绑定异常
<!-- myGridObject = new myTemplatedControl(); -->
<!-- myGridObject.DataContext = new myTypeCollection(); -->
<!-- NOTE: collection obviously is NOT empty in the real code -->
<sdk:DataGrid ItemsSource={Binding DataContext}> 
    <sdk:DataGridTemplateColumn Width="Auto">
        <sdk:DataGridTemplateColumn.HeaderStyle>
            <Style TargetType="sdk:DataGridColumnHeader">
                <Setter Property="ContentTemplate">
                    <Setter.Value>
                        <DataTemplate>

                            <!-- ?????? write out Ptotal in the header of the column ??????? -->
                            <!-- This throws a binding-related ArgumentException -->
                            <TextBlock Text="{Binding ???? Ptotal ?????}" />

    <!-- closing tags cut off -->
    <sdk:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding P}" />
    <!-- closing tags cut off once more-->
    <TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, 
AncestorType={x:Type myTemplatedControl}}, Path=DataContext.Ptotal}" />
<TextBlock Text="{Binding ElementName=yourElementName, Path=DataContext.Ptotal}" />
<TextBlock Text="{Binding Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType=sdk:DataGrid, AncestorLevel=1}, Path=DataContext.Count}"