双向绑定到一组基本数据类型

Two-way binding to an array of basic data types

ItemsControl 绑定到 System.Double 数组,同时能够将更改推回到底层元素的最佳方法是什么?

详情

我正在使用 ItemsControl 为用户提供一组垂直指南。底层 VM 对象将这些指南的位置提供为 double[]。我将此数组绑定到 ItemsSource 并将我的指南正确定位在 ItemsControl 中(使用 Transform)。到目前为止一切顺利。

但是,这些指南需要进行调整。我的 ItemsControlItemTemplate 提供了一个 Thumb 用户可以使用它来调整指南的位置。但是,由于底层元素是一个内在类型(double),更改显然不会推回源(或者我错了吗?!)

我现在正朝着创建 DoubleByRef class 的方向前进,即基本上是 double class 和类型为 double 的成员 Value(希望这很清楚,大声笑)。但只是想与社区确认是否有更好的东西。

当您将 ItemsSource 绑定到集合(或数组)时,将为集合中的每个元素生成一个项目容器。每个容器的数据上下文都指向源集合中的相应元素,这意味着项容器中的任何绑定都使用该元素作为其绑定源。虽然您当然可以对可通过通过 绑定源访问的任何值设置双向绑定,但您不能对源本身设置双向绑定。没有办法做到这一点,因为绑定只知道元素的 value;它对包含该元素的集合一无所知。由于它不知道该值从何而来,因此无法替换它。事实上,对于像 double[] 这样的值类型的集合,绑定源甚至不是数组中的 相同的 值——它是一个盒装副本。

使这项工作像您设想的那样工作的唯一方法是将准则值包装在一些引用类型的包装器中,就像您建议的 DoubleByRef。然后您将能够设置到包装值的双向绑定。

您可能还有另一个问题,即数组不支持集合更改通知。如果你的值的数量总是固定的,这对你来说可能不是问题,你可以绑定到一个DoubleByRef[]。 但是,如果可以添加或删除值,则需要将您的值包装在实现 INotifyCollectionChanged 的集合中。 ObservableCollection<DoubleByRef> 可以。

顺便说一句,WPF 确实包含一个 DoubleCollection,但它并没有真正解决元素绑定问题,也没有实现更改通知。你想猜猜它的用途吗?是的——指南!