Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/14.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
.net 字典类型问题,如果给定特定文本,则获取等效的字典键或字典值?_.net_Vb.net_Winforms_Listview_Dictionary - Fatal编程技术网

.net 字典类型问题,如果给定特定文本,则获取等效的字典键或字典值?

.net 字典类型问题,如果给定特定文本,则获取等效的字典键或字典值?,.net,vb.net,winforms,listview,dictionary,.net,Vb.net,Winforms,Listview,Dictionary,我有一个字典(string,string),我使用字典值设置目录路径,使用键为每个值设置描述 Por示例: Value of a random item of my dictionary: "C:\Test" Key name of that item = "Test folder" 好的,现在在我的应用程序中,我有一个选项可以选择是显示描述还是完整的目录路径,问题是 一些图像可以理解它: 1-我在这里存储/管理字典中的项目: 2-我可以选中此复选框以在组合框中显示字典键或字典值(您将在下图

我有一个字典(string,string),我使用字典值设置目录路径,使用键为每个值设置描述

Por示例:

Value of a random item of my dictionary: "C:\Test"
Key name of that item = "Test folder"
好的,现在在我的应用程序中,我有一个选项可以选择是显示描述还是完整的目录路径,问题是

一些图像可以理解它:

1-我在这里存储/管理字典中的项目:

2-我可以选中此复选框以在组合框中显示字典键或字典值(您将在下图中看到):

3-选中“说明”复选框,说明将显示在组合框中,当我添加项目时,它将与所选的combobox.text一起添加(可以是说明或完整路径)

4-现在我取消选中描述复选框,我想要的是更改listview的描述,就像我将combobox的描述更改为等效的完整路径一样(但我要更改组合框名称的方法是重新加载字典,因为它是按字母顺序排序的,所以…我不知道如何对listview子项执行相同的操作)

我想提醒您,listview子项文本可以是描述,也可以是完整路径,因此我需要在这两个备选方案中进行更改

…这是我的代码:

(请阅读评论)

首先 “'Item.SubItems(2.Text)”可以是描述,也可以是完整路径,因此我需要同时使用这两个选项 如果ListView\u Monitor.Items.Count为0,则 作为ListView\u Monitor.Items中的ListViewItem的每个项目 如果是ShowDescriptions,则“Showdescription”是用于显示描述或完整路径的布尔变量 '说明存储在“Dictionary.Key”中 “我不知道如何获取项目的键名 'Item.SubItems(2).Text=目录\u SendTo.keys。。。 'CType(项.子项(2).文本,目录\u发送到…) 否则如果不显示描述,则“不显示描述,我将显示完整路径” '完整路径存储在“Dictionary.Value”中 '记住“Item.SubItems(2.Text)”可以是描述或完整路径 '因此,如果“Item.SubItems(2.Text)”是描述,那么这段代码可以工作,因为字典键名与描述名称相同 Item.SubItems(2).Text=目录\发送到(Item.SubItems(2).Text) '在这里,如果“Item.SubItems(2).Text”是目录路径而不是描述,我需要一个替代选项 如果结束 下一个 如果结束 更新:

解决方案(目前)

我的问题是,我是否可以改进这段代码(可能是为了不在dict中循环):

如果ListView\u Monitor.Items.Count为0,则
作为ListView\u Monitor.Items中的ListViewItem的每个项目
如果显示说明,则“显示说明”
对于目录\u SendTo.Values中的每个值
如果值=项。子项(2)。文本,则
Item.SubItems(2).Text=FindKeyByValue(目录_SendTo,Item.SubItems(2).Text)
如果结束
下一个
否则,如果不显示描述,则“显示完整路径”
对于目录\u SendTo.Keys中的每个键
如果key=Item.SubItems(2.Text),则
Item.SubItems(2).Text=目录\发送到(键)
如果结束
下一个
如果结束
下一个
如果结束
公共函数FindKeyByValue(属于TKey,TValue)(字典作为字典(属于TKey,TValue),值作为TValue)作为TKey
对于字典中作为KeyValuePair(TKey,TValue的)的每一对
如果value.Equals(pair.value),则返回pair.Key
下一个
'抛出新异常(“在字典中找不到该值。”)
一无所获
端函数

如果这是我的应用程序,我会将UI元素更改为datagridview,以便绑定包含自定义类的集合,并根据需要隐藏或显示相应的列

这种方法将允许您在将来轻松添加其他属性列,而无需担心当前面临的问题。它还允许您将UI扩展到其他平台(移动、web),而无需在UI中添加大量硬编码信息

例如,我将创建以下类和集合来保存有关文件的信息:

Public Class FileDetails
    Public Property Index As Integer
    Public Property Description As String = String.Empty
    Public Property FullFileName As String = String.Empty
    Public ReadOnly Property FileName As String
        Get
            If Not String.IsNullOrEmpty(Me.FullFileName) Then
                Return System.IO.Path.GetFileName(Me.FullFileName)
            Else
                Return String.Empty
            End If
        End Get
    End Property
    Public ReadOnly Property Directory As String
        Get
            If Not String.IsNullOrEmpty(Me.FullFileName) Then
                Return System.IO.Path.GetDirectoryName(Me.FullFileName)
            Else
                Return String.Empty
            End If
        End Get
    End Property
End Class

Public Class FileDetailsCollection
    Inherits System.ComponentModel.BindingList(Of FileDetails)

End Class
下面是我将在表单级别声明的私有成员变量,用于保存信息:

Private m_Collection As FileDetailsCollection
此方法用于使用一些示例数据填充集合:

Private Sub LoadCollection()
    Dim wIndex As Integer
    m_Collection = New FileDetailsCollection
    For Each sFileName As String In System.IO.Directory.GetFiles("c:\", "*.*")
        Dim oFileDetails As New FileDetails

        oFileDetails.FullFileName = sFileName
        wIndex += 1
        oFileDetails.Index = wIndex
        oFileDetails.Description = "Test " & wIndex.ToString

        m_Collection.Add(oFileDetails)
    Next
End Sub
此方法在网格上执行初始配置,包括将显示的列的定义:

Private Sub ConfigureGrid()
    With Me.DataGridView1
        .AutoGenerateColumns = False
        .Columns.Add(New DataGridViewTextBoxColumn With {.DataPropertyName = "Index", .Name = .DataPropertyName, .HeaderText = "Index"})
        .Columns.Add(New DataGridViewTextBoxColumn With {.DataPropertyName = "FullFileName", .Name = .DataPropertyName, .HeaderText = "Song"})
        .Columns.Add(New DataGridViewTextBoxColumn With {.DataPropertyName = "Description", .Name = .DataPropertyName, .HeaderText = "Description"})
        .Columns.Add(New DataGridViewTextBoxColumn With {.DataPropertyName = "Directory", .Name = .DataPropertyName, .HeaderText = "Description"})

        .DataSource = m_Collection
    End With
End Sub
此方法为当前选项更改配置可见列(相当于您的复选框):

最后,我们执行初始化和表单启动:

Sub New()

    ' This call is required by the designer.
    InitializeComponent()

    Call LoadCollection()
    Call LoadGrid()
    Call ConfigureColumnsForOptionChange()

End Sub
并在用户更改复选框值时更新UI:

Private Sub CheckBox1_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles CheckBox1.CheckedChanged
    Call ConfigureColumnsForOptionChange()
End Sub

要回答第二个问题,关于如何改进正在使用的循环,可以对其进行显著改进。目前,如果列表视图中有100个项目,目录中有10个项目,则代码将至少循环1000次,最多循环10次,具体取决于目录中使用的值以及是否显示已标记描述

我们可以通过在进入赋值循环之前使用适当的键构建字典,将直接循环减少到110倍:

    If ListView_Monitor.Items.Count <> 0 Then
        Dim DirectoriesByCurrentKey As New Dictionary(Of String, String)

        If ShowDescriptions Then
            ' If we are showing the descriptions, add each of the items to the new collection, keyed by the value
            For Each key In Directories_SendTo.Keys
                Dim Description As String
                Description = Directories_SendTo(key)
                ' We don't know if description is unique, so make sure that we don't get a runtime error if we 
                ' try to add the same description multiple time
                If Not DirectoriesByCurrentKey.ContainsKey(Description) Then
                    DirectoriesByCurrentKey.Add(Description, key)
                End If
            Next
        Else
            ' Just use the current collection
            DirectoriesByCurrentKey = Directories_SendTo
        End If

        For Each Item As ListViewItem In ListView_Monitor.Items
            Dim sDescription As String = ""
            ' Try to find the current description using the current list item description
            If DirectoriesByCurrentKey.TryGetValue(Item.SubItems(2).Text, sDescription) Then
                ' If we found the entry, change the description to what we found
                Item.SubItems(2).Text = sDescription
            End If
        Next
    End If
如果ListView\u Monitor.Items.Count为0,则
Dim DirectoriesByCurrentKey作为新字典(字符串的,字符串的)
Sub New()

    ' This call is required by the designer.
    InitializeComponent()

    Call LoadCollection()
    Call LoadGrid()
    Call ConfigureColumnsForOptionChange()

End Sub
Private Sub CheckBox1_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles CheckBox1.CheckedChanged
    Call ConfigureColumnsForOptionChange()
End Sub
    If ListView_Monitor.Items.Count <> 0 Then
        Dim DirectoriesByCurrentKey As New Dictionary(Of String, String)

        If ShowDescriptions Then
            ' If we are showing the descriptions, add each of the items to the new collection, keyed by the value
            For Each key In Directories_SendTo.Keys
                Dim Description As String
                Description = Directories_SendTo(key)
                ' We don't know if description is unique, so make sure that we don't get a runtime error if we 
                ' try to add the same description multiple time
                If Not DirectoriesByCurrentKey.ContainsKey(Description) Then
                    DirectoriesByCurrentKey.Add(Description, key)
                End If
            Next
        Else
            ' Just use the current collection
            DirectoriesByCurrentKey = Directories_SendTo
        End If

        For Each Item As ListViewItem In ListView_Monitor.Items
            Dim sDescription As String = ""
            ' Try to find the current description using the current list item description
            If DirectoriesByCurrentKey.TryGetValue(Item.SubItems(2).Text, sDescription) Then
                ' If we found the entry, change the description to what we found
                Item.SubItems(2).Text = sDescription
            End If
        Next
    End If