【发布时间】:2011-12-15 19:12:23
【问题描述】:
我有一个业务对象 - 称它为 Fish(不是从任何东西派生的,即不是 DependancyObject),它使用 DataTemplate 显示在 ListBox 中。在代码中的其他地方,我需要通过对 Fish 的引用来了解 Fish DataTemplate 的 TextBlock 部分的渲染宽度。没问题,我想。我向 Fish 类添加了宽度和高度属性,并在我的数据模板中使用 Mode=OnwayToSource 将 TextBlock 宽度/高度绑定到这些属性。
问题:设置我的 Fish.width/heigh 属性时,宽度/高度始终为 NaN。我试过这个解决方法:
OneWayToSource Binding seems broken in .NET 4.0
但它也不起作用(值始终为 NaN)。
我无法绑定到 ActualWidth/ActualHeight,因为它们是只读的(为什么我不能在只读属性上绑定 OnwayToSource !!)
我有什么替代方案?我必须从中派生 Fish DependancyObject 并使我的属性成为 DP?
XAML:
<DataTemplate DataType="{x:Type p:Fish}">
<Border BorderBrush="Black" BorderThickness="2" >
<TextBlock FontSize="14" TextAlignment="Center" VerticalAlignment="Center"
Width="{Binding Path=width, Mode=OneWayToSource}"
Height="{Binding Path=height, Mode=OneWayToSource}" ...
代码:
class Fish {
public double width { get; set; } // From DataTemplate TextBlock.Width.
public double height { get; set; } // From DataTemplate TextBlock.Height
}
...
double rendered_width = my_fish.width; // Use the rendered width!
【问题讨论】:
-
您使用了错误的绑定模式。请参阅 BalamBalam 的回答。您链接到的问题与绑定在更新后无法获取绑定属性的方式有关,与此问题无关。您只想阅读 - 使用 Mode=OneWay。您只想写 - 使用 Mode=OneWayToSource。
-
要么我对不清楚感到困惑(要么可能!)。 TextBlock 呈现并具有宽度/实际宽度。我想将该值推送到我的业务(鱼)对象宽度属性 - 所以我可以从代码中的鱼中读取它。所以我的模板中 TextBlock 上的绑定需要是 OnewayToSource - 将 TextBlock.Width 写入 Fish.width
-
据我了解,这正是 OneWayToSource 存在的原因 - 通过将绑定放在源对象而不是目标上来反转绑定,从而绑定到不是依赖属性的对象上的属性。
-
哦,我明白你现在在说什么了。 OneWayToSource 存在的真正原因是您可以在 UI 中设置一个值来更改 VM 中的绑定值,但对 VM 中的值的更改不会影响 UI 中的元素。绑定到只读属性不起作用的原因是因为它仍在尝试在 UI 元素(宽度/高度)更改时执行 Get - 根据您链接到的问题。
-
看起来你不能按照你想要的方式向后使用绑定。您真正应该做的是将鱼宽度绑定到文本块宽度,而不是将文本块宽度“反向绑定”到鱼宽度。如果您的属性(fish.Width / fish.Height)仅存在于您的 .cs 代码中,那么您的绑定应该在 .cs 代码中定义。