绑定 OnwayToSource 未按预期工作 - 有什么替代方案?
我有一个业务对象 - 称之为 Fish(不是从任何东西派生的,即不是 DependancyObject),它使用 DataTemplate 显示在 ListBox 中。在代码中的其他位置,我需要通过对 Fish 的引用来了解 Fish DataTemplate 的 TextBlock 部分的渲染宽度。我想没问题。我向 Fish 类添加了宽度和高度属性,并在我的数据模板中使用 Mode=OnwayToSource 将 TextBlock 宽度/高度绑定到这些属性。
问题:设置 Fish.width/heigh 属性时,宽度/高度始终为 NaN。我尝试了这个解决方法:
OneWayToSource 绑定在 .NET 4.0 中似乎已损坏
但它也不起作用(值始终为 NaN)。
我无法绑定到 ActualWidth/ActualHeight,因为它们是只读的(为什么我不能在只读属性上绑定 OnwayToSource!!)
我有哪些替代方案?我是否必须从 DependancyObject 派生 Fish 并使我的属性成为 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!
Ive a business object - call it Fish (not derived from anything ie not a DependancyObject) that is displayed in a ListBox using a DataTemplate. Else where in code I need to know the rendered width of the TextBlock part of the Fish DataTemplate through a reference to a Fish. No problem I thought. I added a width and height properties to Fish class and in my data template I bound the TextBlock width/height to these using Mode=OnwayToSource.
Problem: the Width/Height are always NaN when setting my Fish.width/heigh properties. I tried this workaround:
OneWayToSource Binding seems broken in .NET 4.0
but it doesnt work either (value is always NaN).
I cant bind to ActualWidth/ActualHeight because they are read only (why can't I bind OnwayToSource on a readonly property!!)
What alternatives do I have? Do I have to derive Fish from DependancyObject and make my properties DPs?
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}" ...
Code:
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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我终于意识到你想要做什么,你是对的,它应该有效。然而,WPF 并不同意。我发现这是一个问题,其他有之前有,但这显然是设计使然。即使您只想绑定 OneWayToSource,也无法在只读属性上设置绑定。
这是一个具有相同问题的问题: OneWayToSource 绑定来自 XAML 中的只读属性 他们的解决方法是在 xaml 元素周围放置一个容器(具有读/写宽度/高度),并在该容器上设置绑定。这可能对你有用。
Microsoft Connect 上有一个与此相关的未解决问题,据称这是设计造成的:http://connect.microsoft.com/VisualStudio/feedback/details/540833/onewaytosource-binding-from-a-readonly-dependency-property。有人在 相关线程使用转换器。您可以尝试一下,但我不确定它是否适合您的情况,因为它们的绑定是自定义控件,而不是内置框架元素。
更好
在此解决方案中,Boogaart 提出了一个定义新附加属性(类似于 DockPanel.Dock="Top")的实现,它允许任何元素提供其宽度和高度以供观察:
尝试一下,看看是否合适。
I've finally realized what you're trying to do, and you're right that it should work. WPF, however, disagrees. I see that it's a problem that others have had before, but that is apparently by design. You can't set up a binding on a read only property, even if you're just wanting to bind OneWayToSource.
Here is a question with the same problem: OneWayToSource binding from readonly property in XAML Their workaround was to put a container (which has read/write width/height) around the xaml element and set up the binding on that container. This might work for you.
There is an unresolved issue related to this on Microsoft Connect where it is claimed to be behaviour by design: http://connect.microsoft.com/VisualStudio/feedback/details/540833/onewaytosource-binding-from-a-readonly-dependency-property. Someone claims a workaround in the related thread which uses a converter. You can try it, but I'm not sure it'll work in your case, as their binding was to a custom control, not a built in framework element.
Even Better
In This Solution, Boogaart came up with an implementation defining a new attached property (Similar to DockPanel.Dock="Top") which allows any element to provide its width and height for observation:
Try it on and see if it fits.
如果您在执行某种操作(即按下按钮或单击超链接)后使用这些属性,则可以通过命令的 CommandParameter 传入 ActualWidth 和 Height。否则,我建议使用触发器,例如此处提供的触发器:
http: //expressionblend.codeplex.com/wikipage?title=Behaviors%20and%20Effects&referringTitle=文档
I同意 OneWayToSource 绑定不适用于只读依赖属性,这似乎违反直觉。
If you consume these properties after some sort of action i.e. a button press or click on a hyperlink, then you can pass in the the ActualWidth and Height via a CommandParameter of a command. Otherwise I would suggest using triggers such as the ones available here:
http://expressionblend.codeplex.com/wikipage?title=Behaviors%20and%20Effects&referringTitle=Documentation
I agree that it appears counter intuitive that OneWayToSource bindings don't work on read only dependency properties.
尝试绑定 OneWay。我认为 OneWayToSource 是指想要写入源。
http://msdn.microsoft.com/en-us /library/system.windows.data.bindingmode.aspx
我做了一个测试,果然 Width = NaN 直到宽度被分配(设置)。我知道这不是您想要的行为。试试这个。在指定宽度的地方报告它(如 200)。如果未分配宽度,则报告为 NaN。但实际宽度是正确的。 ActualWidth 就在那里,但显然您尝试获取它的方式不起作用。
有趣的是,按钮确实报告了正确的 ActualWidth,但 Width 为 NaN。
Try binding OneWay. I think OneWayToSource is means wants to write to the source.
http://msdn.microsoft.com/en-us/library/system.windows.data.bindingmode.aspx
I did a test and sure enough Width = NaN until width is Assigned (set). I understand this is not the behavior you want. Try this. Where the Width is assigned it is reported (as 200). Where the Width is not assigned it is reported as NaN. But ActualWidth IS correct. ActualWidth is there but clearly the way you are trying to get it is not working.
What is interesting is the Button does report the correct ActualWidth but Width is NaN.