如何获取放置在DataTemplate中的元素的绝对屏幕坐标



我有一个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;
    }

最新更新