我有一个ListView,它使用UserControl作为DataTemplate:
<ListView>
<ListView.ItemTemplate>
<DataTemplate>
<views:TaskerInfoView />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
我需要放置在TaskerInfoView用户控件中的按钮的绝对屏幕坐标。
我试过这个代码:
var newButtonPoint = button.PointToScreen(new Point(0, 0));
但我收到了异常"This Visual未连接到PresentationSource",我想是因为按钮在DataTemplate内部,所以它未连接到视觉元素。
更新我已经找到了收到该异常的原因:在PointToScreen
调用之前,我将项目移动到OberstableCollection中,即ListView:的ItemsSource
this._taskList.Move(currentIndex, currentIndex - 1); // _taskList is the ObservableCollection<>
var newButtonPoint = button.PointToScreen(new Point(0, 0));
如果我移除ObservableCollection<>.Move
,则PointToScreen工作正常。
我认为ObservableCollection<>.Move
在内部删除了该项,并在新位置插入了另一项。引发异常是因为button
包含对已移除元素的引用,该元素实际上已与TreeVisual 断开连接
例如:
xaml:
<ListBox x:Name="myListBox" SelectedIndex="2">
<ListBoxItem>1</ListBoxItem>
<ListBoxItem>2</ListBoxItem>
<ListBoxItem>3</ListBoxItem>
<ListBoxItem>4</ListBoxItem>
<ListBoxItem>5</ListBoxItem>
</ListBox>
<Button Content="GetIndexFromContainer" Click="Button_Click" />
cs:
private void Button_Click(object sender, RoutedEventArgs e)
{
var index = GetSelectedIndexFromList();
}
private int GetSelectedIndexFromList()
{
var container = myListBox.ItemContainerGenerator.ContainerFromItem(MyListBox.SelectedItem);
var index = myListBox.ItemContainerGenerator.IndexFromContainer(container);
return index;
}