在我的应用程序中,我们有一个视图模型对象,我们FrameworkElement
使用我们的自定义函数从该对象中检索其附加GetVisualChildWithDataContext
(见下文)。
发生的情况是,此函数返回一个ContentPresenter
对象,其ActualWidth
和ActualHeight
属性为 0。由于我的内容由 24x24 矩形组成,因此我希望这 2 个属性的值为 24。
我的问题是,我怎样才能通过只有一个视图模型来检索我期望的值(ActualWidth
和24)?ActualHeight
如果有更好的方法可以做到这一点,我会全力以赴。
谢谢你的时间。(见下面的示例)
xml:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:l="clr-namespace:WpfApplication2"
Title="MainWindow"
Width="525"
Height="350">
<Canvas x:Name="_RootCanvas">
<ItemsControl Margin="-5,0,0,0" ItemsSource="{Binding MyItems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type l:MyItem}">
<Canvas>
<Rectangle
Canvas.Left="{Binding ActualLeft}"
IsHitTestVisible="True"
Margin="0,0,0,0"
Width="24"
Height="24"
Fill="Black" />
</Canvas>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button Canvas.Top="50" Width="100" Height="30" Click="Button_Clicked">
<TextBlock Text="Button" />
</Button>
</Canvas>
</Window>
后面的代码:
private MyItem _MyItem;
public MainWindow()
{
InitializeComponent();
_MyItem = new MyItem(0);
MyItems = new ObservableCollection<MyItem>();
MyItems.Add(_MyItem);
DataContext = this;
}
public ObservableCollection<MyItem> MyItems { get; set; }
public void Button_Clicked(object sender, RoutedEventArgs e)
{
FrameworkElement fe = GetVisualChildWithDataContext(_RootCanvas, _MyItem);
}
public static FrameworkElement GetVisualChildWithDataContext(DependencyObject parent, object dataContext)
{
int count = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < count; i++)
{
DependencyObject d = VisualTreeHelper.GetChild(parent, i);
FrameworkElement element = d as FrameworkElement;
if (element != null)
{
if (element.DataContext == dataContext)
return element;
var f = GetVisualChildWithDataContext(element, dataContext);
if (f != null)
return f;
}
}
return null;
}
public class MyItem
{
public MyItem(double left)
{
ActualLeft = left;
}
public double ActualLeft { get; set; }
}