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

时间:2013-09-01 17:05:44

标签: c# wpf coordinates

我有一个使用UserControl作为DataTemplate的ListView:

<ListView>
    <ListView.ItemTemplate>
        <DataTemplate>
            <views:TaskerInfoView />
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

我需要在TaskerInfoView用户控件中放置Button的绝对屏幕坐标。

我尝试使用此代码:

var newButtonPoint = button.PointToScreen(new Point(0, 0));

但我收到异常“此Visual未连接到PresentationSource”我想是因为该按钮位于DataTemplate中,因此它没有连接到可视元素。

UPDATE 我已经找到了为什么我收到了这个异常:在PointToScreen调用之前我将项目移动到ObersvableCollection中,即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断开的已删除元素的引用

1 个答案:

答案 0 :(得分:1)

例如:

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;
    }