【问题标题】:Binding to Datagrid's ItemsSource collection properties instead of single items绑定到 Datagrid 的 ItemsSource 集合属性而不是单个项目
【发布时间】:2012-04-18 13:52:03
【问题描述】:

我在尝试绑定集合中的一些属性而不是元素的属性时感到困惑。 我什至不确定如何正确表达它...代码可能会更好地解释:这里是类型(不是实际代码,我已将其缩短为基础):

public class myType
{
    public int P {get;set;}
}
public class myTypeCollection : ObservableCollection<myType>
{
    public int Ptotal {get { return 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 如下所示: (添加 cmets 使其尽可能清晰)

<!-- 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-->

{Binding P} 按预期工作,因为P 是项目的属性,但我如何访问集合的属性,如PtotalPmin 等?

感谢您抽出宝贵时间阅读本文。如果缺少任何信息,请指出,我会发布它。

【问题讨论】:

  • 重新标记以澄清它是 Silveright 4

标签: c# binding silverlight-4.0 collections datagrid


【解决方案1】:

我认为问题在于 DataGrid 绑定到集合,并且每一行都绑定到单个项目,而不是集合。您需要获得更高级别的访问权限(回到集合本身)。

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

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

否则可能创建对上下文的静态访问以通过绑定 Source 访问它

【讨论】:

  • AncestorTypeAncestorLevelRelativeSource 类型上似乎不存在,不幸的是,代码原样无法编译。
  • 我认为这只适用于 Silverlight 5,你能升级你的项目吗?
  • 不幸的是,由于谁知道原因,客户不想更新运行时。无论如何感谢您的建议,我会将其保存在我自己的小 sn-p 存储库中以供将来参考。
【解决方案2】:

所以你需要集合对象作为你的绑定源。

你需要这些:

RelativeSource MarkupExtension

Binding.RelativeSource Property

类似这样的东西(未测试):

    <TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, 
AncestorType={x:Type myTemplatedControl}}, Path=DataContext.Ptotal}" />

如果 DataGrid 在您的自定义 myTemplatedControl 内。我并不完全清楚 myGridObject 到底是什么。主要思想是:

正如 MSDN 文档所说:Binding.RelativeSource Gets or sets the binding source by specifying its location relative to the position of the binding target.

如果您坚持使用 x:Type 扩展,这里有一个关于它的链接,因此您可以将它与您的自定义控件一起使用:

X:Type

另一种方法是,如果您命名您的容器元素(您的集合是数据上下文),那么您可以将该元素设置为绑定源:

<TextBlock Text="{Binding ElementName=yourElementName, Path=DataContext.Ptotal}" />

【讨论】:

  • 谢谢。我正在尝试“另一种方法”,看起来恰到好处。
  • 代码今天不想遵守:elementName 方法已经解决了异常,但文本块仍然是空白。会多调点。澄清一下,myGridObject 是“主”应用程序中模板化控件的名称
  • 调试应用时在VS的输出窗口中检查绑定异常。有绑定异常吗?
  • 我刚刚尝试了您的第一种方法,Visual Studio 抱怨 AncestorType 就像它对其他答案的建议所做的那样。我正在考虑放弃并组成一堆依赖属性来独立处理标题......
  • 您使用什么版本的 Silverlight?版本 4 中不存在 RelativeSource。但您应该可以使用 ElementName 解决方案。可能绑定路径不正确。调试时应该会在输出中看到绑定异常
【解决方案3】:

结果客户改变了对网格标题的看法,他不想再在标题中显示总计。

顺便说一句,我一定尝试了 20 种不同的方法,包括在各种类型的转换器中打补丁,但我无法完成这个看起来并不简单的任务。

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

【讨论】:

    猜你喜欢
    • 2017-09-18
    • 1970-01-01
    • 1970-01-01
    • 2018-07-16
    • 1970-01-01
    • 2023-03-07
    • 2015-05-24
    • 1970-01-01
    • 2012-01-01
    相关资源
    最近更新 更多