【问题标题】:Using Binding.Source without using resources在不使用资源的情况下使用 Binding.Source
【发布时间】:2012-02-09 14:57:30
【问题描述】:

我的以下代码运行良好:

<Viewbox.Resources>
    <CollectionViewSource x:Key="viewSource"
                          Source="{Binding Path=SelectionList}">
        <CollectionViewSource.SortDescriptions>
            <scm:SortDescription PropertyName="Description" />
        </CollectionViewSource.SortDescriptions>
    </CollectionViewSource>

</Viewbox.Resources>
<ComboBox ItemsSource="{Binding Source={StaticResource ResourceKey=viewSource}}"/>

我想将我的 CollectionViewSource 直接放在我的 ComboBox 中,而不使用任何类似的资源:

<ComboBox SelectedItem="{Binding Path=Value, Mode=TwoWay}">
    <ComboBox.ItemsSource>
        <Binding>
            <Binding.Source>
                <CollectionViewSource Source="{Binding Path=SelectionList}">
                    <CollectionViewSource.SortDescriptions>
                        <scm:SortDescription PropertyName="Description" />
                    </CollectionViewSource.SortDescriptions>
                </CollectionViewSource>
            </Binding.Source>
        </Binding>
    </ComboBox.ItemsSource>
</ComboBox>

但是这样我的 ComboBox 总是空的,我得到以下绑定错误:

System.Windows.Data 错误:2:找不到管理 FrameworkElement 或 FrameworkContentElement 为目标元素。 绑定表达式:路径=选择列表;数据项=空;目标元素是 'CollectionViewSource' (HashCode=1374711);目标属性是“源” (类型“对象”)

有谁知道我该怎么做?

【问题讨论】:

  • 这只是一个猜测,但您可能必须显式设置 CollectionViewSource.Source 绑定的 Source:&lt;CollectionViewSource Source="{Binding Source=... Path=SelectionList}"。您是否看到任何绑定错误消息?
  • 感谢您的评论,我检查了我的装订错误。根据您的建议,我可以在 Source=... 中添加什么
  • 将其设置为拥有 SelectionList 属性的对象。
  • SelectionList 在 ViewModel/DataContext 中定义。我试过 但它不起作用。
  • @Nicolas 明确地说,我认为他是指非绑定源,例如{RelativeSource Self},然后绑定到DataContext.SelectionList 属性

标签: wpf


【解决方案1】:

Nicolas,虽然这不是您问题的答案,因为它仍然使用资源,但您可以通过在其本地资源字典中定义 CollectionViewSource 将其放入 ComboBox:

<ComboBox>
    <ComboBox.Resources>
        <CollectionViewSource x:Key="viewSource" Source="{Binding Path=SelectionList}">
            <CollectionViewSource.SortDescriptions>
                <scm:SortDescription PropertyName="Description" />
            </CollectionViewSource.SortDescriptions>
        </CollectionViewSource>
    </ComboBox.Resources>
    <ComboBox.ItemsSource>
        <Binding Source="{StaticResource viewSource}"/>
    </ComboBox.ItemsSource>
</ComboBox>

【讨论】:

  • @H.B.这个答案已经过大量编辑,评论指的是旧答案。旧的解决方案确实不起作用。
  • 总结一下:CollectionViewSource 不知道DataContext,也没有办法将DataContext 交给他,因为CollectionViewSource 不在VisualTree 中。所以唯一的方法是使用资源。 Clemens 和@Rachel,感谢您的专业知识。
【解决方案2】:

您收到错误是因为 CollectionViewSource 没有父级可从其继承 DataContext 以在绑定中使用。

你不需要为你的 ComboBox 使用CollectionViewSource。您可以通过绑定ItemsSource 属性将其项目源绑定到任何集合

<ComboBox ItemsSource="{Binding SelectionList}"
          SelectedItem="{Binding Path=Value, Mode=TwoWay}" />

唯一缺少的是排序,但是您可以在将 ViewModel 中的数据返回给视图之前对其进行排序。

【讨论】:

  • 感谢您的回答。我真的需要在我的视图中排序,而不是在我的 ViewModel 中,这就是我使用 CollectionViewSource 的原因。你能告诉我为什么它在资源中而不是在 ComboBox 中起作用。
  • @Nicolas 它作为资源工作,因为Binding.Source 属性指向已在 UI 中定义的对象。此外,您不能对不是DependencyProperty 的属性使用绑定,而且我认为Binding.Source 不是DependencyProperty。根据您的原始集合创建一个从 ViewModel 返回排序的 CollectionViewSource 的属性没有任何问题。
  • @Rachel,这里设置的不是Binding的Source,而是CollectionViewSource的Source。
  • @Clemens 哦,对了,忘了 :) 在这种情况下,它不起作用,因为 CollectionViewSource 不是可视树或逻辑树的一部分,因此没有可以从中继承 DataContext 的父级从在绑定中使用。更新了我的答案。
  • @Rachel 对,这就是为什么 CollectionViewSource.Source 的绑定需要明确的 Source 设置,即拥有 SelectionList 属性的对象。
猜你喜欢
  • 1970-01-01
  • 2020-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-15
  • 1970-01-01
  • 2021-08-18
相关资源
最近更新 更多