Что нового

[Элементы GUI] ListView - форматирование и сортировка

inx

Знающий
Сообщения
43
Репутация
12
Есть Input, есть ListView

При вводе в Input и нажатии Enter ищется это значение (код) в ListView и добавляется "1" в соответствующую колонку к уже существующему значению (изначально там 0).
Нужно чтобы при первом "+1" менялась иконка с красной на желтую.
При достижении равного значения в предыдущем столбце - на зеленую.
При превышении - на синюю.

И как можно сделать сортировку по иконкам? Например все зеленые внизу, красные наверху, желтые посередине?
Сделать пустой столбец, в котором будут только иконки, присваивать каждой строчке при смене иконки какой-нибудь атрибут через _GUICtrlListView_SetItemParam, потом читать ListView в массив, сортировать по атрибутам и заново заполнять ListView ?
Это можно сделать работающим одновременно с _GUICtrlListView_SortItems ? (Клик на пустом столбце с цветными иконками - сортирует по цвету). Или проще в столбец с иконками записывать "Недостача"/"Лишка" и т.п. - и будет сортировка по тексту?

Код:
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#include <ListViewConstants.au3>
#include <Array.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <File.au3>


#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 751, 432, 209, 245)
$Input1 = GUICtrlCreateInput("", 24, 24, 113, 21)

$hListView = GUICtrlCreateListView("Код|Наименование|Всего, шт|Пересчет, шт", 24, 64, 705, 345)

_GUICtrlListView_SetColumnWidth($hListView, 0, 200)
_GUICtrlListView_SetColumnWidth($hListView, 1, 100)
_GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_DOUBLEBUFFER))


$hImage = _GUIImageList_Create(11, 11)
_GUIImageList_Add($hImage, _WinAPI_CreateSolidBitmap(GUICtrlGetHandle($hListView), 0xFF0000, 11, 11)) ; red
_GUIImageList_Add($hImage, _WinAPI_CreateSolidBitmap(GUICtrlGetHandle($hListView), 0x00FF00, 11, 11)) ; green
_GUIImageList_Add($hImage, _WinAPI_CreateSolidBitmap(GUICtrlGetHandle($hListView), 0xFFFF00, 11, 11)) ; yellow
_GUIImageList_Add($hImage, _WinAPI_CreateSolidBitmap(GUICtrlGetHandle($hListView), 0x0000FF, 11, 11)) ; blue


_GUICtrlListView_SetImageList($hListView, $hImage, 1)


GUISetState(@SW_SHOW)

$aList = _LoadList()
For $i = 0 To UBound($aList) - 1
	_GUICtrlListView_AddItem($hListView, $aList[$i][0])
	_GUICtrlListView_SetItemParam($hListView, $i, $aList[$i][0])
	_GUICtrlListView_AddSubItem($hListView, $i, $aList[$i][1], 1)
	_GUICtrlListView_AddSubItem($hListView, $i, $aList[$i][2], 2)

Next
_GUICtrlListView_RegisterSortCallBack($hListView)

$accEnter = GUICtrlCreateDummy()
Global $a_AccelKeys[1][2] = [["{ENTER}", $accEnter]]
GUISetAccelerators($a_AccelKeys)
GUISetState()



#EndRegion ### END Koda GUI section ###

While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
		Case $hListView
			_GUICtrlListView_SortItems($hListView, GUICtrlGetState($hListView))
		Case $accEnter
			If _GuiCtrlGetFocus($Form1) = $Input1 Then
;~ 				MsgBox(0, "", "Enter Pressed in $Input1")
				$tInfo = DllStructCreate($tagLVFINDINFO)
				DllStructSetData($tInfo, "Flags", $LVFI_PARAM)
				DllStructSetData($tInfo, "Param", GUICtrlRead($Input1))
				$iI = _GUICtrlListView_FindItem($hListView, -1, $tInfo)
;~ 				MsgBox(0, "Information", "Target Item Index: " & $iI)
				_GUICtrlListView_EnsureVisible($hListView, $iI)
				$iI = _GUICtrlListView_FindItem($hListView, -1, $tInfo)
				$aArrayItemAttributes = _GUICtrlListView_GetItem ( $hListView, $iI, 3 )
				_GUICtrlListView_AddSubItem($hListView, $iI, Number($aArrayItemAttributes[3]) + 1, 3)
			Else
				GUISetAccelerators("")
				ControlSend($Form1, "", _GuiCtrlGetFocus($Form1), "{ENTER}")
				GUISetAccelerators($a_AccelKeys)
			EndIf
	EndSwitch
WEnd

Func _LoadList()
	Local $aArray
	Local $sFilePath = @ScriptDir & "\list.ini"
	_FileReadToArray($sFilePath, $aArray, 0) ;прочитаем файл в массив (по строкам) без возврата кол-ва элементов.
	$aArray = _Array_1d_to_2d($aArray, 3, @TAB)
	Return $aArray
EndFunc   ;==>_LoadList

;~ Преобразуем 1d массив в 2d
Func _Array_1d_to_2d($arr, $cols, $dlm)
	Local $array2D[UBound($arr)][$cols]
	For $i = 0 To UBound($arr) - 1
		$aTemp = StringSplit($arr[$i], $dlm) ; Делим на элементы по разделителю
		If UBound($aTemp) < ($cols + 1) Then ; Временный фикс для случаев, когда в одной из строчек меньше элементов, чем ожидается
			ReDim $aTemp[$cols]
			_ArrayAdd($aTemp, "") ; В случае если N-ый элемент пустой.
		EndIf
		For $j = 0 To UBound($array2D, 2) - 1
			$array2D[$i][$j] = $aTemp[$j + 1] ; Записываем элементы в 2d массив
		Next
	Next
	Return ($array2D)
EndFunc   ;==>_Array_1d_to_2d

Func _GuiCtrlGetFocus($hGui = "")
	Local $InputID = ControlGetHandle($hGui, "", ControlGetFocus($hGui))
	Return _ControlGetGuiID($InputID)
EndFunc   ;==>_GuiCtrlGetFocus

Func _ControlGetGuiID($hCtrl)
	Local $Result = DllCall("user32.dll", "int", "GetDlgCtrlID", "hwnd", $hCtrl)
	If @error = 0 Then Return $Result[0]
	Return SetError(1, 0, '')
EndFunc   ;==>_ControlGetGuiID


P.S. Список в ListView загружается из list.ini (разделитель - табуляция):
Код:
001	Стул	5
006	Стол	5
012	Кресло	2
018	Холодильник	1
020	Велосипед	2
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
246
С цветом можно так :
Код:
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#include <ListViewConstants.au3>
#include <Array.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <File.au3>


#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 751, 432, 209, 245)
$Input1 = GUICtrlCreateInput("", 24, 24, 113, 21)

$hListView = GUICtrlCreateListView("Код|Наименование|Всего, шт|Пересчет, шт", 24, 64, 705, 345)

_GUICtrlListView_SetColumnWidth($hListView, 0, 200)
_GUICtrlListView_SetColumnWidth($hListView, 1, 100)
_GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_DOUBLEBUFFER))


$hImage = _GUIImageList_Create(11, 11)
_GUIImageList_Add($hImage, _WinAPI_CreateSolidBitmap(GUICtrlGetHandle($hListView), 0xFF0000, 11, 11)) ; red
_GUIImageList_Add($hImage, _WinAPI_CreateSolidBitmap(GUICtrlGetHandle($hListView), 0x00FF00, 11, 11)) ; green
_GUIImageList_Add($hImage, _WinAPI_CreateSolidBitmap(GUICtrlGetHandle($hListView), 0xFFFF00, 11, 11)) ; yellow
_GUIImageList_Add($hImage, _WinAPI_CreateSolidBitmap(GUICtrlGetHandle($hListView), 0x0000FF, 11, 11)) ; blue


_GUICtrlListView_SetImageList($hListView, $hImage, 1)


GUISetState(@SW_SHOW)

$aList = _LoadList()
For $i = 0 To UBound($aList) - 1
	_GUICtrlListView_AddItem($hListView, $aList[$i][0])
	_GUICtrlListView_SetItemParam($hListView, $i, $aList[$i][0])
	_GUICtrlListView_AddSubItem($hListView, $i, $aList[$i][1], 1)
	_GUICtrlListView_AddSubItem($hListView, $i, $aList[$i][2], 2)

Next
_GUICtrlListView_RegisterSortCallBack($hListView)

$accEnter = GUICtrlCreateDummy()
Global $a_AccelKeys[1][2] = [["{ENTER}", $accEnter]]
GUISetAccelerators($a_AccelKeys)
GUISetState()



#EndRegion ### END Koda GUI section ###

While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
		Case $hListView
			_GUICtrlListView_SortItems($hListView, GUICtrlGetState($hListView))
		Case $accEnter
			If _GuiCtrlGetFocus($Form1) = $Input1 Then
;~              MsgBox(0, "", "Enter Pressed in $Input1")
				$tInfo = DllStructCreate($tagLVFINDINFO)
				DllStructSetData($tInfo, "Flags", $LVFI_PARAM)
				DllStructSetData($tInfo, "Param", GUICtrlRead($Input1))
				$iI = _GUICtrlListView_FindItem($hListView, -1, $tInfo)
;~              MsgBox(0, "Information", "Target Item Index: " & $iI)
				_GUICtrlListView_EnsureVisible($hListView, $iI)
;~                $iI = _GUICtrlListView_FindItem($hListView, -1, $tInfo)
				$aArrayItemAttributes = _GUICtrlListView_GetItem($hListView, $iI, 3)
				_GUICtrlListView_AddSubItem($hListView, $iI, Number($aArrayItemAttributes[3]) + 1, 3)
				$aText = _GUICtrlListView_GetItemTextArray($hListView, $iI)
				$iDelta = $aText[3] - $aText[4]
				Select
					Case $iDelta = 0
						_GUICtrlListView_SetItemImage($hListView, $iI, 1)
					Case $iDelta > 0
						_GUICtrlListView_SetItemImage($hListView, $iI, 2)
					Case $iDelta < 0
						_GUICtrlListView_SetItemImage($hListView, $iI, 3)
				EndSelect


			Else
				GUISetAccelerators("")
				ControlSend($Form1, "", _GuiCtrlGetFocus($Form1), "{ENTER}")
				GUISetAccelerators($a_AccelKeys)
			EndIf
	EndSwitch
WEnd

Func _LoadList()
	Local $aArray
	Local $sFilePath = @ScriptDir & "\list.ini"
	_FileReadToArray($sFilePath, $aArray, 0) ;прочитаем файл в массив (по строкам) без возврата кол-ва элементов.
	$aArray = _Array_1d_to_2d($aArray, 3, @TAB)
	Return $aArray
EndFunc   ;==>_LoadList

;~ Преобразуем 1d массив в 2d
Func _Array_1d_to_2d($arr, $cols, $dlm)
	Local $array2D[UBound($arr)][$cols]
	For $i = 0 To UBound($arr) - 1
		$aTemp = StringSplit($arr[$i], $dlm) ; Делим на элементы по разделителю
		If UBound($aTemp) < ($cols + 1) Then ; Временный фикс для случаев, когда в одной из строчек меньше элементов, чем ожидается
			ReDim $aTemp[$cols]
			_ArrayAdd($aTemp, "") ; В случае если N-ый элемент пустой.
		EndIf
		For $j = 0 To UBound($array2D, 2) - 1
			$array2D[$i][$j] = $aTemp[$j + 1] ; Записываем элементы в 2d массив
		Next
	Next
	Return ($array2D)
EndFunc   ;==>_Array_1d_to_2d

Func _GuiCtrlGetFocus($hGui = "")
	Local $InputID = ControlGetHandle($hGui, "", ControlGetFocus($hGui))
	Return _ControlGetGuiID($InputID)
EndFunc   ;==>_GuiCtrlGetFocus

Func _ControlGetGuiID($hCtrl)
	Local $Result = DllCall("user32.dll", "int", "GetDlgCtrlID", "hwnd", $hCtrl)
	If @error = 0 Then Return $Result[0]
	Return SetError(1, 0, '')
EndFunc   ;==>_ControlGetGuiID
Сортировки пока нет
Для сортировки можно добавить ещё одну колонку с разницей в ListView, что-бы её небыло видно - сделать ширину "0" и производить сортировку по этой колонке, только обычным
Код:
_GUICtrlListView_SimpleSort
как-то коряво всё получается :stars:
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Если я правильно понял задумку:

Код:
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#include <ListViewConstants.au3>
#include <Array.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <File.au3>

$Form1 = GUICreate("Form1", 751, 432)
$Input1 = GUICtrlCreateInput("", 24, 24, 113, 21)

$hListView = GUICtrlCreateListView("|Код|Наименование|Всего, шт|Пересчет, шт|Color", 24, 64, 705, 345)

_GUICtrlListView_SetColumnWidth($hListView, 0, 200)
_GUICtrlListView_SetColumnWidth($hListView, 1, 100)
_GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_DOUBLEBUFFER))

$hImage = _GUIImageList_Create(11, 11)

$iImage_Red = _GUIImageList_Add($hImage, _WinAPI_CreateSolidBitmap(GUICtrlGetHandle($hListView), 0xFF0000, 11, 11)) ; red
$iImage_Green = _GUIImageList_Add($hImage, _WinAPI_CreateSolidBitmap(GUICtrlGetHandle($hListView), 0x00FF00, 11, 11)) ; green
$iImage_Yellow = _GUIImageList_Add($hImage, _WinAPI_CreateSolidBitmap(GUICtrlGetHandle($hListView), 0xFFFF00, 11, 11)) ; yellow
$iImage_Blue = _GUIImageList_Add($hImage, _WinAPI_CreateSolidBitmap(GUICtrlGetHandle($hListView), 0x0000FF, 11, 11)) ; blue

_GUICtrlListView_SetImageList($hListView, $hImage, 1)

GUISetState(@SW_SHOW)

$aList = _LoadList()

For $i = 0 To UBound($aList) - 1
	_GUICtrlListView_AddItem($hListView, '', $iImage_Red, $aList[$i][0])
	_GUICtrlListView_AddSubItem($hListView, $i, $aList[$i][0], 1)
	_GUICtrlListView_AddSubItem($hListView, $i, $aList[$i][1], 2)
	_GUICtrlListView_AddSubItem($hListView, $i, $aList[$i][2], 3)
	_GUICtrlListView_AddSubItem($hListView, $i, $iImage_Red, 4)
Next

_GUICtrlListView_HideColumn($hListView, 5)
_GUICtrlListView_SetColumnWidth($hListView, 0, 20)
_GUICtrlListView_RegisterSortCallBack($hListView)

$accEnter = GUICtrlCreateDummy()
Global $a_AccelKeys[1][2] = [["{ENTER}", $accEnter]]
GUISetAccelerators($a_AccelKeys)

GUISetState()

While 1
	$nMsg = GUIGetMsg()
	
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
		Case $accEnter
			If ControlGetHandle($Form1, '', ControlGetFocus($Form1)) <> GUICtrlGetHandle($Input1) Then
				ContinueLoop
			EndIf
			
			$iItem = _GUICtrlListView_FindParam($hListView, GUICtrlRead($Input1))
			
			If $iItem <> -1 Then
				_GUICtrlListView_EnsureVisible($hListView, $iItem)
				
				$iNum = Number(_GUICtrlListView_GetItemText($hListView, $iItem, 4)) + 1
				$iPrevNum = Number(_GUICtrlListView_GetItemText($hListView, $iItem, 3))
				
				_GUICtrlListView_SetItemText($hListView, $iItem, $iNum, 4)
				
				$iImage = -1
				
				Switch $iNum
					Case 1
						$iImage = $iImage_Yellow
					Case $iPrevNum
						$iImage = $iImage_Green
					Case Else
						If $iNum > $iPrevNum Then
							$iImage = $iImage_Blue
						Else
							ContinueLoop
						EndIf
				EndSwitch
				
				_GUICtrlListView_SetItemText($hListView, $iItem, $iImage, 5)
				_GUICtrlListView_SetItemImage($hListView, $iItem, $iImage)
			EndIf
		Case $hListView
			$iCol = GUICtrlGetState($hListView)
			
			If $iCol = 0 Then
				_GUICtrlListView_SortItems($hListView, 5)
				
				$hHeader = _GUICtrlListView_GetHeader($hListView)
				$iFormat = _GUICtrlHeader_GetItemFormat($hHeader, 5)
				
				_GUICtrlHeader_SetItemFormat($hHeader, $iCol, $iFormat)
				_GUICtrlHeader_SetItemFormat($hHeader, 5, $HDF_STRING)
			Else
				_GUICtrlListView_SortItems($hListView, $iCol)
			EndIf
	EndSwitch
WEnd

Func _LoadList()
	Local $aArray
	Local $sFilePath = @DesktopDir & "\list.ini"
	_FileReadToArray($sFilePath, $aArray, 0) ;прочитаем файл в массив (по строкам) без возврата кол-ва элементов.
	$aArray = _Array_1d_to_2d($aArray, 3, @TAB)
	Return $aArray
EndFunc ;==>_LoadList

;~ Преобразуем 1d массив в 2d

Func _Array_1d_to_2d($arr, $cols, $dlm)
	Local $array2D[UBound($arr)][$cols]
	For $i = 0 To UBound($arr) - 1
		$aTemp = StringSplit($arr[$i], $dlm) ; Делим на элементы по разделителю
		If UBound($aTemp) < ($cols + 1) Then ; Временный фикс для случаев, когда в одной из строчек меньше элементов, чем ожидается
			ReDim $aTemp[$cols]
			_ArrayAdd($aTemp, "") ; В случае если N-ый элемент пустой.
		EndIf
		For $j = 0 To UBound($array2D, 2) - 1
			$array2D[$i][$j] = $aTemp[$j + 1] ; Записываем элементы в 2d массив
		Next
	Next
	Return($array2D)
EndFunc ;==>_Array_1d_to_2d
 
Автор
I

inx

Знающий
Сообщения
43
Репутация
12
CreatoR сказал(а):
Если я правильно понял задумку:
Да, все работает так как и надо :smile: Спасибо.
Заодно узнал что GUICtrlGetState для ListView возвращает номер "кликнутой" колонки.
 
Верх