我需要访问没有指定宽度的Border的ActualWidth。有人告诉我,我不能在WinRT上这样做,所以我使用了Florian-Gl的代理(来自here)。
问题是我需要在页面的资源上创建代理,如下所示:
<Page.Resources>
<utils:ActualSizePropertyProxy Element="{Binding ElementName=noteBorder}" x:Name="proxy" />
</Page.Resources>
问题在于我无法从资源访问该noteBorder元素,但我可以访问作为Page本身的 pageRoot 。
我想我可以使用ElementName / Path来访问noteBorder。
但是有一些奇怪的东西:
结构类似于:
Page (pageRoot) > Grid > ListView > ListView.ItemTemplate > Grid > Border (noteBorder)
所以,如果我在边框的同一级别创建代理,它将无法运行但如果我将ListView更改为ItemsControl,它将运行并按预期工作。
如果将它设置在边框的同一级别,我将 ElementName 更改为 pageRoot ,它将至少运行。
所以,如果我放了noteBorder(即使我有权访问它),如果我使用的是ListView,它将无法运行,但是可以使用ItemsControl,另一方面,如果我有 pageRoot 它可以解决所有问题。
所以问题是:有没有办法从资源访问 noteBorder ?或者也许是从另一个地方访问它但工作的方法:P
答案 0 :(得分:0)
你应该使用一个项目模板 - 等到你的时候 pageRoot)&gt;网格&gt; ListView或项目控制
在结构的这一点上,您处于您真正想要的元素,即需要您尝试访问的边框的项目的容器。
您应该定义一个Item Template并通过绑定分配ListView的(或ItemsControl的)ItemTemplate属性。
<ListView x:Name="myListView" DataContext="{Binding ToElementIfNotInheritedFromParent}" ItemsSource="{Binding ViewModelListBeingBoundTo}" ItemTemplate="{Binding Source={Static Resource MyCustomItemTemplate}}" />
MyCustomItemTemplate类似于
<DataTemplate x:Name="MyCustomItemTemplate">
<Border x:Name="myBorder" >
<StackPanel>
<TextBlock Text="{Binding Path=Title}" />
<TextBlock Text="{Binding Path=FirstProperty}"/>
<TextBlock Text="{Binding Path=SecondProperty}"/>
</StackPanel>
</Border>
</DataTemplate>
然后在你的Codebehind中(或者如果ViewModel使用后面的代码将ListView对象传递给ViewModel)
DataTemplate dt = this.myListView.Items[indexOfChoice].ItemTemplate as DataTemplate;
Border b = dt.LoadContent() as Border;
int actualWidth = b.AcutalWidth
OR
You can create a FindControl() method that runs recursively to extract the actual control within the border, for instance if you wanted to access one of the Textboxes.
这里的代码在这里: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/a612f5a6-e05e-4b68-a813-893eeda159cc