【问题标题】:Listview - select mosti similar item to valueListview - 选择与价值最相似的项目
【发布时间】:2014-04-09 16:38:54
【问题描述】:

如何在列表视图(第一列)中选择与字符串值最相似的项目,例如标签或文本框。

Listview 填充了以下代码:

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    ListView1.Items.Clear()
    ListView1.View = System.Windows.Forms.View.Details
    ListView1.Columns.Add("COL1", 100, HorizontalAlignment.Left) 'KONTO
    ListView1.Columns.Add("COL2", 140, HorizontalAlignment.Left) 'NAZIV

    Dim FilePath As String = "W:\GLAVNI\KOR14\"
    Dim DBF_File As String = "MATIKGL"
    Dim ColName As String = "KONTO"
    'Dim naz As String
    Using con As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & FilePath & _
    " ;Extended Properties=dBASE IV")
        con.Open()
        Using cmd As New OleDbCommand("SELECT * FROM MATIKGL ORDER BY KONTO, NAZIV", con)
            Using reader As OleDbDataReader = cmd.ExecuteReader()
                If reader.HasRows Then
                    While (reader.Read())
                        Me.ListView1.Items.Add(reader("KONTO"))
                        'ListView1.Items(i).SubItems.Add(rdr.Item("YourColumnName").ToString)
                        'BELOW SELECTS ALL ITEMS THAT STARTS WITH 2020-
                        For i = 0 To ListView1.Items.Count - 1
                            If ListView1.Items(i).ToString.Contains("2020-") Then

                            Else
                                ListView1.Items.Remove(ListView1.Items(i))
                            End If
                        Next

                    End While

                Else

                End If
            End Using
        End Using
        con.Close()
    End Using
End Sub

我有一个文本框和一个按钮。 来自文本框的文本输入应与列表视图中的所有项目进行比较,并应选择最接近的项目。 还有一件事:所有项目都按字母顺序排序

按钮代码是:

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    ListView1.MultiSelect = False
    ListView1.FullRowSelect = True

    Dim checkInt As Integer = FindItem(ListView1, "2020-" & TextBox1.Text)'this one is changed since all items starts with "2020-"& UCASE TEXT
    If checkInt <> -1 Then

        ListView1.Items(checkInt).Selected = True
        ListView1.Focus()

    Else
        Label1.Text = "Search string not found"
    End If
End Sub

更新代码

            Dim checkInt As Integer = FindItem(ListView1, "2020-" & TextBox3.Text)

        If checkInt <> -1 Then

            TextBox4.Focus()

        Else
            Label14.Text = "NEMA"
            On Error GoTo ext
            Dim li As ListViewItem
            ListView1.SelectedItems.Clear()
            ListView1.HideSelection = False

            li = ListView1.FindItemWithText("2020-" & UCase(TextBox3.Text))

            If Not (li Is Nothing) Then
                Me.ListView1.Focus()
                li.Selected = True
                li.EnsureVisible()
            ElseIf li Is Nothing Then
                li = ListView1.FindItemWithText("2020-" & Strings.Left(TextBox3.Text, 1))
                Me.ListView1.Focus()
                li.Selected = True
                li.EnsureVisible()
            Else

            End If

            Exit Sub
ext:

            TextBox3.Text = ""
            TextBox3.Focus()
            Label14.Text = "String not found"



        End If

这个有效。

我知道这不是最好的解决方案,但它确实有效。 无需您的帮助即可解决此问题,谢谢 Phillip Trelford

【问题讨论】:

  • 你对相似度的定义是什么?你试过string.Contains()吗?还是正则表达式?
  • 您能帮我解决这些功能吗(我从未使用过它们)。假设 listview 中有三个值:“Alpha”、“Apple”和“Ask”如果我输入“Ann”我希望选择 Apple,如果输入例如“Arm”,“Apple”将是选择。如果找到第一个字母,则搜索第二个字母,依此类推,当未找到字母时,根据该模式选择最接近的值。
  • 如果您清楚地了解“相似”的含义,您可以编写一个算法,为每个项目从 0(完全匹配)开始得分,然后向上,然后返回最低分数。不是简单地进入正则表达式。
  • 我知道如何在 Excel 中使用 VLOOKUP 函数执行此操作,但在 VB 中无法执行此操作。 ...在字符串术语中最接近(字母)

标签: vb.net listview similarity


【解决方案1】:

定义一个函数来对两个字符串的接近度进行评分,然后使用 LINQ 找到最低分数,即。

' Example score function
Function Score(a As String, b As String) As Integer
    Dim index = 0
    While index < a.Length And index < b.Length
        Dim diff = Math.Abs(AscW(a(index)) - AscW(b(index)))
        If diff <> 0 Then Return diff
        index += 1
    End While
    Return Math.Abs(a.Length - b.Length)
End Function

Function Closest(searchWord As String, words As String()) As String
    Dim ordered =
        From w In words
        Select Word = w, Score = Score(w, searchWord)
        Order By Score

    Return ordered.First().Word
End Function

Sub Main()
    Dim words = {"Alpha", "Apple", "Ask"}
    Dim searchWord = "Ann"
    Dim word = Closest(searchWord, words)
    Console.WriteLine(word)
End Sub

更新

要在 WinForms ListView 中选择值,您需要大致执行以下操作:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ListView1.MultiSelect = False
ListView1.FullRowSelect = True

Dim prefix = "2020-"
' Extract items from Listview
Dim items = New List(Of String)()
For Each item In ListView1.Items
    items.Add(item)
Next
Dim words = items.ToArray()
Dim searchWord = TextBox1.Text
Dim resultWord = Closest(searchWord, words)
'this one is changed since all items starts with "2020-"& UCASE TEXT
Dim checkInt As Integer = FindItem(ListView1, prefix & resultWord) 
If checkInt <> -1 Then

    ListView1.Items(checkInt).Selected = True
    ListView1.Focus()

Else
    Label1.Text = "Search string not found"
End If
End Sub

【讨论】:

  • 谢谢,请问如何申请listview1?我知道如何将它应用于文本框Dim searchWord = UCase(TextBox1.Text)... 这行应该改为指向listview1列,但我不知道如何Dim words = {"Alpha", "Apple", "Ask"}
  • @JovicaBozic 您应该能够使用您用来分配给 ListView.Items 的集合中的单词,否则从该值中读取。要在 ListView 中选择单词,请使用 SelectedItems (WinForms) 或 SelectedValue (WPF)。
  • 然后我有“类型的值 - 无法转换为字符串的一维数组”错误/更正 words 在这一行 Dim word = Closest(searchWord, words)
  • @JovicaBozic 如果您从 ListView.Items 中提取单词,您可能需要转换为字符串数组,即 ListView.Items.Select(Function(w) w.ToString()).ToArray ()。抱歉,没有您的源代码副本,我很难为您提供准确的解决方案。
  • @JovicaBozic 抱歉,刚刚重新阅读了您之前的评论,您在items.Add(TextBox1.Text.ToString) 处将所有项目都作为搜索词。您需要添加项目。请改用items.Add(item.ToString)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多