【问题标题】:why does my wpf custom component listbox fire twice?为什么我的 wpf 自定义组件列表框会触发两次?
【发布时间】:2013-06-19 22:53:28
【问题描述】:

这个类(下)是一个自定义组件。它应该只是通过单击扩展器内的列表来搜索文件夹。

ExpanderList 是扩展器中的列表

DirMaker 是真正的扩展器

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;

namespace BigHand
{
/// <summary>
/// Interaction logic for DirMakerControl.xaml
/// </summary>
public partial class DirMakerControl : UserControl
{
    string currentDirectory = "c:/";        
    DirectoryInfo di;
    bool directoryEmpty;

    public DirMakerControl()
    {
        this.InitializeComponent();

        getFolders();
        updateHeader();
    }

    private void getFolders()
    {
        ExpanderList.Items.Clear();
        try
        {
            di = new DirectoryInfo(currentDirectory);

            foreach (DirectoryInfo d in di.GetDirectories())
            {
                ExpanderList.Items.Add(d.ToString());
            }

        }
        catch (UnauthorizedAccessException)
        {
            //goBack() keeps display the same
            goBack();
            MessageBox.Show("                 SORRY!!!! \nYou dont have the correct \npermisions to use these files.");
        }

        if (ExpanderList.Items.Count == 0)
        {
            directoryEmpty = true;
            ExpanderList.IsEnabled = false;
            ExpanderList.Items.Add("No Folders Here");
        }
        else
        {
            directoryEmpty = false;
            ExpanderList.IsEnabled = true;
        }

        updateHeader();
    }

    private void ListClicked(object sender, SelectionChangedEventArgs e)
    {
        // If selected index is -1 (no selection) do nothing  
        if (ExpanderList.SelectedIndex != -1)
        {

            //update list and variables
            if (!directoryEmpty)
            {
                ExpanderList.IsEnabled = true;
                currentDirectory = currentDirectory + ExpanderList.SelectedItem + "/";

                // Reset selected index to -1 (no selection)  
                ExpanderList.SelectedIndex = -1;

                getFolders();
            }
        }

    }

    private void goBack()
    {
        currentDirectory = currentDirectory.Substring(0, getCurrentFolderStringIndex());

        getFolders();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        goBack();
    }

    //returns an integer representing where the current folder name starts in the current folder string
    public int getCurrentFolderStringIndex()
    {
        char[] currentD = currentDirectory.ToCharArray();

        for (int index = currentD.Length - 2; index >= 0; index--)
        {
            if (currentD[index] == '/')
            {
                return index + 1;                    
            }
        }

        //if this gets called(should at least start back at the c:/)
        return 0;

    }

    private void updateHeader()
    {
        //Change Header
        //get temp int to save calling the method twice
        int index = getCurrentFolderStringIndex();

        if (index == 0)            
            DirMaker.Header = currentDirectory;            
        else
        DirMaker.Header = currentDirectory.Substring(index, currentDirectory.Length - index);
    }

    private void selectionMade(ListBox sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        // TODO: Add event handler implementation here.
        // If selected index is -1 (no selection) do nothing  
        if (ExpanderList.SelectedIndex == -1)
            return;

        //update list and variables
        if (!directoryEmpty)
        {
            ExpanderList.IsEnabled = true;
            currentDirectory = currentDirectory + ExpanderList.SelectedItem + "/";

            // Reset selected index to -1 (no selection)  
            ExpanderList.SelectedIndex = -1;

            getFolders();
        }          

    }

}
}

它真的很好用,除了私有 void ListClicked(object sender, SelectionChangedEventArgs e) 有时会触发不止一次,其效果是跳到更深的文件,然后按预期的级别进行。当我在 if 上放置断点时,这种行为似乎不会重复 (ExpanderList.SelectedIndex != -1) 行,它总是返回 -1 并在不应该发生的情况下阻止这种情况。我已经看到证据表明这种方法存在错误?虽然我没有经验或正面指责别人.....绝对是我,虽然这个选项一直在我脑海中发挥作用,因为我不能找到一个反复触发的原因。

真的很重要,我要尽快查明真相,这让我发疯了

提前感谢您的帮助

约翰·哈里斯

【问题讨论】:

  • 我知道底部方法 selectionMade 不起作用在写这篇文章的时候根本没有被调用,并且已经被完全删除

标签: c# wpf listbox expander


【解决方案1】:

直接使用 ListBox.Items 属性并不是一个好主意:您应该首先在 临时集合(一个简单的 List)中运行您的文件夹检索,完成后您批量更新列表框:

ExpanderList.Items.Clear();
foreach (string s in tmp)
{
    ExpanderList.Items.Add(s);
}

至少这会更优化,但请检查这是否也解决了您的问题。 :)

【讨论】:

  • 谢谢你的时间不完全一样: foreach (DirectoryInfo d in di.GetDirectories()) { ExpanderList.Items.Add(d.ToString()); }
  • 不知道为什么,但我认为您的扫描是递归的。 :( 所以你可以使用相同的想法,但有一个绑定:你只需在更新时将集合交换为最新的,这样只有一次刷新。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-26
  • 2012-01-09
  • 2014-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多