Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在没有SelectedIndex或类似内容的情况下获取列表框项目的索引(在PreviewMouseDown中,尚未“选择”任何内容)_C#_Wpf_Listbox_Visualtreehelper - Fatal编程技术网

C# 如何在没有SelectedIndex或类似内容的情况下获取列表框项目的索引(在PreviewMouseDown中,尚未“选择”任何内容)

C# 如何在没有SelectedIndex或类似内容的情况下获取列表框项目的索引(在PreviewMouseDown中,尚未“选择”任何内容),c#,wpf,listbox,visualtreehelper,C#,Wpf,Listbox,Visualtreehelper,如何实现下面的GetListBoxItemIndex函数来获取我单击的项目的索引?我尝试使用VisualTreeHelper,但没有成功(这意味着,VisualTreeHelper显然有效,但我在树搜索中没有任何进展…) private void MyListBox\u OnPreviewMouseDown(对象发送器,鼠标按钮ventargs e){ var listBox=发送方作为列表框; var src=e.OriginalSource作为DependencyObject; if(src

如何实现下面的
GetListBoxItemIndex
函数来获取我单击的项目的索引?我尝试使用
VisualTreeHelper
,但没有成功(这意味着,
VisualTreeHelper
显然有效,但我在树搜索中没有任何进展…)

private void MyListBox\u OnPreviewMouseDown(对象发送器,鼠标按钮ventargs e){
var listBox=发送方作为列表框;
var src=e.OriginalSource作为DependencyObject;
if(src==null | | listBox==null)返回;
var i=GetListBoxItemIndex(listBox,src);
DragDrop.DoDragDrop(src,BoundCollection[i],DragDropEffects.Copy);
//边界集合定义为:
//可观测集合边界集合
}

请注意,在此状态下尚未选择任何内容,因为这是一个
PreviewMouseDown
事件以下代码将帮助您解决问题,步骤在注释中

private void ListBox_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    // you can check which mouse button, its state, or use the correct event.

    // get the element the mouse is currently over
    var uie = ListBox.InputHitTest(Mouse.GetPosition(this.ListBox));

    if (uie == null)
        return;

    // navigate to its ListBoxItem container
    var listBoxItem = FindParent<ListBoxItem>((FrameworkElement) uie);

    // in case the click was not over a listBoxItem
    if (listBoxItem == null)
         return;

    // here is the index
    int index = this.ListBox.ItemContainerGenerator.IndexFromContainer(listBoxItem);
    MessageBox.Show(index.ToString());
}

public static T FindParent<T>(FrameworkElement child) where T : DependencyObject
{
    T parent = null;
    var currentParent = VisualTreeHelper.GetParent(child);

    while (currentParent != null)
    {

       // check the current parent
       if (currentParent is T)
       {
          parent = (T)currentParent;
          break;
       }

       // find the next parent
       currentParent = VisualTreeHelper.GetParent(currentParent);
    }

    return parent;
}
private void ListBox\u OnPreviewMouseDown(对象发送器,鼠标按钮ventargs e)
{
//您可以检查哪个鼠标按钮、其状态或使用正确的事件。
//获取鼠标当前所在的元素
var uie=ListBox.InputHitTest(Mouse.GetPosition(this.ListBox));
if(uie==null)
返回;
//导航到其ListBoxItem容器
var listBoxItem=FindParent((FrameworkElement)uie);
//如果单击不是在listBoxItem上
如果(listBoxItem==null)
返回;
//这是索引
int index=this.ListBox.ItemContainerGenerator.IndexFromContainer(listBoxItem);
Show(index.ToString());
}
公共静态T FindParent(FrameworkElement子级),其中T:DependencyObject
{
T parent=null;
var currentParent=VisualTreeHelper.GetParent(子级);
while(currentParent!=null)
{
//检查当前父级
如果(当前父项为T)
{
父项=(T)当前父项;
打破
}
//找到下一个家长
currentParent=VisualTreeHelper.GetParent(currentParent);
}
返回父母;
}
更新

您需要的是单击的数据项的索引。获取容器后,只有通过
DataContext
获取与其关联的数据项并在绑定集合中查找其索引,才能获取索引。
ItemContainerGenerator
已经为您完成了这项工作

在代码中,您假设
ListBoxItem
索引与绑定集合中的数据项的索引相同,只有禁用了
Virtualization
时才是如此。如果启用,则仅实例化可见区域中项目的容器。例如,如果绑定集合中有1000个数据项,并且已滚动到第50个数据项,那么从理论上讲,索引0处的
ListBoxItem
将绑定到第50个数据项,这证明您的假设是错误的


我在前面理论上说过,因为当
虚拟化
开启时,会在滚动区域的顶部和底部创建一些隐藏容器,以便键盘导航正常工作。

以下代码将帮助您解决问题,步骤在注释中

private void ListBox_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    // you can check which mouse button, its state, or use the correct event.

    // get the element the mouse is currently over
    var uie = ListBox.InputHitTest(Mouse.GetPosition(this.ListBox));

    if (uie == null)
        return;

    // navigate to its ListBoxItem container
    var listBoxItem = FindParent<ListBoxItem>((FrameworkElement) uie);

    // in case the click was not over a listBoxItem
    if (listBoxItem == null)
         return;

    // here is the index
    int index = this.ListBox.ItemContainerGenerator.IndexFromContainer(listBoxItem);
    MessageBox.Show(index.ToString());
}

public static T FindParent<T>(FrameworkElement child) where T : DependencyObject
{
    T parent = null;
    var currentParent = VisualTreeHelper.GetParent(child);

    while (currentParent != null)
    {

       // check the current parent
       if (currentParent is T)
       {
          parent = (T)currentParent;
          break;
       }

       // find the next parent
       currentParent = VisualTreeHelper.GetParent(currentParent);
    }

    return parent;
}
private void ListBox\u OnPreviewMouseDown(对象发送器,鼠标按钮ventargs e)
{
//您可以检查哪个鼠标按钮、其状态或使用正确的事件。
//获取鼠标当前所在的元素
var uie=ListBox.InputHitTest(Mouse.GetPosition(this.ListBox));
if(uie==null)
返回;
//导航到其ListBoxItem容器
var listBoxItem=FindParent((FrameworkElement)uie);
//如果单击不是在listBoxItem上
如果(listBoxItem==null)
返回;
//这是索引
int index=this.ListBox.ItemContainerGenerator.IndexFromContainer(listBoxItem);
Show(index.ToString());
}
公共静态T FindParent(FrameworkElement子级),其中T:DependencyObject
{
T parent=null;
var currentParent=VisualTreeHelper.GetParent(子级);
while(currentParent!=null)
{
//检查当前父级
如果(当前父项为T)
{
父项=(T)当前父项;
打破
}
//找到下一个家长
currentParent=VisualTreeHelper.GetParent(currentParent);
}
返回父母;
}
更新

您需要的是单击的数据项的索引。获取容器后,只有通过
DataContext
获取与其关联的数据项并在绑定集合中查找其索引,才能获取索引。
ItemContainerGenerator
已经为您完成了这项工作

在代码中,您假设
ListBoxItem
索引与绑定集合中的数据项的索引相同,只有禁用了
Virtualization
时才是如此。如果启用,则仅实例化可见区域中项目的容器。例如,如果绑定集合中有1000个数据项,并且已滚动到第50个数据项,那么从理论上讲,索引0处的
ListBoxItem
将绑定到第50个数据项,这证明您的假设是错误的


我在前面理论上说过,因为当
虚拟化
开启时,会在滚动区域的顶部和底部创建一些隐藏容器,以便键盘导航正常工作。

以下代码将帮助您解决问题,步骤在注释中

private void ListBox_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    // you can check which mouse button, its state, or use the correct event.

    // get the element the mouse is currently over
    var uie = ListBox.InputHitTest(Mouse.GetPosition(this.ListBox));

    if (uie == null)
        return;

    // navigate to its ListBoxItem container
    var listBoxItem = FindParent<ListBoxItem>((FrameworkElement) uie);

    // in case the click was not over a listBoxItem
    if (listBoxItem == null)
         return;

    // here is the index
    int index = this.ListBox.ItemContainerGenerator.IndexFromContainer(listBoxItem);
    MessageBox.Show(index.ToString());
}

public static T FindParent<T>(FrameworkElement child) where T : DependencyObject
{
    T parent = null;
    var currentParent = VisualTreeHelper.GetParent(child);

    while (currentParent != null)
    {

       // check the current parent
       if (currentParent is T)
       {
          parent = (T)currentParent;
          break;
       }

       // find the next parent
       currentParent = VisualTreeHelper.GetParent(currentParent);
    }

    return parent;
}
private void ListBox\u OnPreviewMouseDown(对象发送器,鼠标按钮ventargs e)
{
//您可以检查哪个鼠标按钮、其状态或使用正确的事件。
//获取鼠标当前所在的元素
var uie=ListBox.InputHit