There is no listview message or style for this.
So, basically No.
However, some imperfect/inefficient workarounds are shown in the link below.
https://stackoverflow.com/questions/...-in-a-listview
Printable View
There is no listview message or style for this.
So, basically No.
However, some imperfect/inefficient workarounds are shown in the link below.
https://stackoverflow.com/questions/...-in-a-listview
I’m using a ListView in report style with checkboxes. Multiselect is False. The idea is that there is always only one item selected, but Multiselect doesn’t stop multiple items being checked. So I added the following code to the ItemCheck event:
This worked fine with the standard ListView, but with the CCListView both checking and unchecking an item fires the ItemCheck event. (Which is logic I guess.)Code:Dim i As Integer
'Uncheck all items
For i = 1 To lvPositionLabels.ListItems.Count
lvPositionLabels.ListItems(i).Checked = False
Next
'Check and select the clicked item
Item.Checked = True
Item.Selected = True
The question is though, how can I ensure only the last clicked item is checked. I’m probably missing something simple, but am stuck…
Please find below a working code snippet:
EDIT: Below way is even more efficient:Code:Private Sub ListView1_ItemCheck(ByVal Item As LvwListItem, ByVal Checked As Boolean)
If Checked = True Then
Dim vItem As Variant, iItem As Long
iItem = Item.Index
With ListView1.ListItems
For Each vItem In ListView1.CheckedIndices
If vItem <> iItem Then .Item(vItem).Checked = False
Next vItem
End With
End If
End Sub
Code:Private Sub ListView1_ItemCheck(ByVal Item As LvwListItem, ByVal Checked As Boolean)
Static iItemPrev As Long
If Checked = True Then
If iItemPrev > 0 Then ListView1.ListItems(iItemPrev).Checked = False
iItemPrev = Item.Index
Else
iItemPrev = 0
End If
End Sub
Thanks for the ListView answer. That fixed my problem! (I really feel like an amateur here at times... :blush:)
I'm slowly but steadily progressing towards the full conversion to the CCR set of controls. One area still to be addressed is the toolbars. I've been playing around for a good few hours with the Toolbar and ImageList controls to figure out how to deal with transparent backgrounds, but haven't been able to find the best way to move forward.
Two key questions:
1. What do you recommend as the format for the images to be in?
2. What is the best way to deal with background transparency?
Toolbar images
Erwin, here's what I do:
PNGs with transparency are stored in a ressource DLL.
On app start I fill VBCCR imagelists by code.
Then I populate the toolbars by code using the imagelists.
Populating the toolbars is very fast.
Transparency works well.
Nothing to complain.
Hi Krool ,
In ListView ,
1- Is it possible to add a Column_Select Event ?
2- In HitTest method , How do I get the item/subitem being clicked ? . It always returns the first column . What should I do to get the (Cell) being clicked ? . I tried various values for the SubitemIndex parameter and got the same results . I have no clue of its purpose or how it is used .
3- Is it possible to highlight only the selected (Cell) . In Full Row Select mode it selects all (Cells) and when disabled it selects the (Cell) from first column . Is it possible to add this feature or there is a workaround for this ?
Below is an example of how to use the SubItemIndex parameter in the HitTest method.
No, maybe a grid fits for this better than a ListView.Code:Private Sub ListView1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim Item As LvwListItem, iSubItem As Integer
Set Item = ListView1.HitTest(X, Y, iSubItem)
If Not Item Is Nothing Then
If iSubItem > 0 Then
Debug.Print Item.ListSubItems(iSubItem).Text
Else
Debug.Print Item.Text
End If
End If
End Sub
Thanks for feedback , but what about point 1 ?
Quote:
1- Is it possible to add a Column_Select Event ?
Krool,
I am using VirtualMode in ListView in Report mode. I need to have the capability to tell the control to refresh/update itself programatically In my file manger I have check boxes and if you turn one off for a folder I want to turn off the check boxes for the files within that folder. I looked in your code for GetVirtualItem because it is what asks me for the updated information and it is only called in the Private Function WindowProcControl which in turn is only called by ISubclass_Message. How do I tell the ListView to update itself? Thanks.
Never mind. The ListView.Refresh sub does just what its name says...
I did set the .VirtualItemCount property. Each time you do that the control starts over and redoes the items in the display but it puts the first item in the list at the top of the display so if the user had scrolled way down in the list then this would jump it back to the top which is not what I wanted. The Refresh sub is exactly what I needed. I can change all of my virtual values (including those that will not be displayed in the current view) and then have it Refresh and it re-reads the values it needs to re-do the display leaving the entry that is at the top where it should be. I don/t know how I overlooked that sub.
Earlier I had tried to do the ListView without the virtual items and it really bogged down when the list got over 50,000 or so. With the virtual item feature it really doesn't matter how many items you have in the list, it only displays a relatively small number of them onscreen and the extra overhead of being virtual is not really noticeable.
Hi krool ,
It will be helpful if you declare the basis on which you ignore some replies on this thread .
This here is all voluntary support. I can ignore or not ignore.
I found a solution to this. The (yet unused) notification LVN_HOTTRACK comes helpful for this.
When processing LVN_HOTTRACK and a criteria is met then sending a LVM_UPDATE message will cause a re-fetch in NM_CUSTOMDRAW.
So I will bring a update soon as this seems quite a straight forward (fix) solution for this issue.
What you mean. You want an event when selecting a column ?
The column will be only selected upon code. So you have full control over it. What would an event benefit ? (beside the fact that there is no LVN_* notification for this)Code:ListView1.SelectedColumn = ColumnHeader
Do my words look offensive or something ? !!!
I understand this is voluntary . It is totally obvious . I did not complain that you don`t provide support . You shared VBCCR to the community and we give feedback including bugs or features . So , we expect some sort of feedback which you already do and million thanks for you efforts . I asked why in some cases you choose to ignore some replies so that I do not fall in this region of ignorance because nobody likes to be ignored , that`s it . It is your post and you are free to decide how you handle it . But this always made me prefer in most cases to not post a bug or feature request being afraid to be ignored or misunderstood . I have a lot to say in this situation but I don`t want to flood the thread with comments that are outside its main scope or purpose .
Sincere thanks , and keep up the good work .
Thanks a lot .Quote:
I found a solution to this. The (yet unused) notification LVN_HOTTRACK comes helpful for this.
When processing LVN_HOTTRACK and a criteria is met then sending a LVM_UPDATE message will cause a re-fetch in NM_CUSTOMDRAW.
So I will bring a update soon as this seems quite a straight forward (fix) solution for this issue.
Yes , this is what I mean .Quote:
What you mean. You want an event when selecting a column ?
The benefit is that there is some routine that I need to call every time a column is selected . Since it seems not possible , I will put that code in every situation that I need to check whether a column is selected or not .Quote:
The column will be only selected upon code. So you have full control over it. What would an event benefit ? (beside the fact that there is no LVN_* notification for this)
If I may put my two cents worth in: the words indeed came across offensive.
Having said that, let's all appreciate that for most of us here, English is not our native language, and that sometimes our words do not come across the way they were intended.
You clarified the misunderstanding, and joined the large group of people who explicitly expressed their gratitude to Krool for the excellent work and support he provides. I personally hope that this is enough to go back to focus on the subject of this thread: Krool's Common Controls Replacements.
Regards,
Erwin
People have different opinions and read different things into words. That doesn't mean that you two should take such a long running, and clearly valuable, thread into the ditch for some personal squabble about nothing.
Knock it off.
Hi Krool,
I saw your edit on TB_SETPADDING in the CCR toolbar. Does that mean that it is not possible to have a little space between the bottom edge of the button and the edge of the toolbar?
Regards,
Erwin
Hi Krool,
Thanks for the quick reply.
I noticed that with the original toolbar, the space above and below the buttons is the same, whereas with the CCR toolbar the buttons are aligned with the bottom of the "bar". See picture below.
Attachment 180614
Then, for some reason I haven't yet figured out, the scaling of other controls on the main screen didn't happen correctly, resulting in the bottom of the CCR being "cut off", which made it look rather strange:
Attachment 180615
However, when I force the resize again, the scaling is done corectly, and the CCR toolbar looks a lot better.
I'd still prefer the look with as much padding below as above, but that's clearly no showstopper.
Regards,
Erwin
Erwin69,
I can't view the images in your post.
Let's try again:
Attachment 180628
Attachment 180629
Erwin
For me it was too cumbersome to maintain the toolbar manually.
Therefore I do it all by code.
If you have a few buttons only, then it is perhaps too much effort.
You need to use the VBCCR imagelist.
Fill it from external DLL, or use LaVolpes image library.
Or use BMP32 and load the images from files.
Many possibilities.
In my case an external DLL was wanted.
First fill the imagelist(s) on app start:
Code:Private Sub InitIconsToolbars()
Dim i As VBCCR.ImageList
Dim R As New c_ResFromDLL
'--------------------------------------------------
R.LibraryFilePath = App.Path & "\RES.dll"
Set i = MF.imgl_Toolbars
StartGDIPlus
i.ListImages.Clear
i.ColorDepth = ImlColorDepth32Bit
i.ImageWidth = 0
i.ImageHeight = 0
ResDLLToImgl i, R, "new"
ResDLLToImgl i, R, "open"
'and 100's more
Set i = Nothing
StopGDIPlus
R.CloseLibrary
Set R = Nothing
End Sub
Filling a toolbar:
Code:Set IL = MF.imgl_Toolbars
ToolbarBackColor = vbWhite
With tbr_Main
.AllowCustomize = False
.BackColor = ToolbarBackColor
.Buttons.Clear
Set .ImageList = IL
.Divider = False
.ShowTips = True
.DoubleBuffer = True
.Transparent = Not True
.MinButtonWidth = 0
.MaxButtonWidth = 0
Set b = .Buttons.Add(, "new", , TbrButtonStyleDefault, "new")
b.ToolTipText = "New"
Set b = .Buttons.Add(, "open", , TbrButtonStyleDefault, "open")
b.ToolTipText = "Open"
.GetIdealSize WS, HS
.Width = WS
.Height = HS
Set b = Nothing
End With
Thanks Karl. I'll need to study this a bit more.
My app has a limited set of buttons, so manually adding these is not the issue. The challenge is more the use of transparency.
I've taken this update as an opportunity to "modernize" the toolbar look and feel. As part of the pre-work, I collected/designed/created a series of images that are all saved in PNG-format with transparency. As that format unfortunately isn't supported by the VBCCR imagelist (and not by the original either), I need to figure out what the best approach is.
Unless it's simple, and you feel that it improves the look and feel of the CCR Toolbar, I wouldn't do anything.
From my point of view it would be a small cosmic improvement that would be nice to have, but most definitely not a showstopper or worth a significant amount of effort.
Karl
could you please elaborate on lines of code you entered
could you please point me to a link where i can get this class c_ResFromDLL, it would be quite helpful for me.Code:Dim R As New c_ResFromDLL
'--------------------------------------------------
R.LibraryFilePath = App.Path & "\RES.dll"
Set i = MF.imgl_Toolbars
StartGDIPlus
i.ListImages.Clear
i.ColorDepth = ImlColorDepth32Bit
i.ImageWidth = 0
i.ImageHeight = 0
ResDLLToImgl i, R, "new"
ResDLLToImgl i, R, "open"
'and 100's more
Set i = Nothing
StopGDIPlus
R.CloseLibrary
Set R = Nothing
also the GDIPlus Library
thanks
Here's the DLL and PNG stuff.
It is quite old and probably there are more elegant solutions.
Also it is a adjusted to my needs.
Attachment 180641
I think #3089 is answered when you inspect the libs.
Hi Krool, don't worry about the extra space below the buttons. As said, it's a small cosmic improvement not worth a lot of trouble. Rest assured that your help is greatly appreciated either way!
However, something is puzzling me with the Toolbar.
The layout of my main screen is a menu-bar and the toolbar on top, and a statusbar at the bottom. In between there is a picturebox that serves as a "container" for a range of other controls.
I assigned 32x32 pixel images to the toolbar buttons using a CCR imagelist, giving the toolbar a Height of 630. This is what I see in the IDE, and what is saved in the frm-file. However, at application startup, the size is reported as 390, which messes up the resizing and positioning of the container and the items in it. After the form-resize event, it actually correctly reports the height of 630 for the toolbar, so I've moved some code around to do the resizing of the other controls at a later stage. Which works fine.
But, now I have the strange thing that the container part of the screen is not painted after the resize and reposition. Only when I move the mouse over the toolbar, or over the statusbar at the bottom, the center of the screen is "refreshed" and properly painted. This happens when the app is run from the IDE as well as compiled.
I realize that this is vague, and for sure don't claim it's related to the CCR toolbar, but I've been killing myself for many hours in the last several days to figure out what is causing this, and still have no clue. Hopefully the description rings a bell for someone to point me in the right direction.
It's the ImageList. Once without (390) and then with (630).
This is a dilemma by design. The ImageList property is saved as string in the CCR ToolBar.
I cannot lookup the ImageList Object during UserControl_ReadProperties as the order in which VB loads the control cannot be influenced.
So doing the lookup in UserControl_ReadProperties would be a luck game. Can work or not.
That's why an inteenal VB.Timer is used for that (only when needed, for ImageList) and it is ensured to fire when everything is safe. However that is AFTER the Form_Load event.
You can FIX this dilemma actually by code in Form_Load:
Code:Set ToolBar1.ImageList = ToolBar1.ImageList ' Force internal lookup now
I use a pager for every toolbar.
This works very well and is only visible when the form is too small to show the full toolbar.
I set the buddy by code, because in the IDE it doesn't work so good.
The toolbar size is correct when I use this after populating the toolbar:
On positioning the toolbar without a pager, I don't care about the toolbar height.Code:.GetIdealSize WS, HS
.Width = WS
.Height = HS
I use the first button as the reference.
This way extra space below the buttons doesn't hurt.
Yet another question on the toolbar...
I've added image lists for the active buttons, and for disabled buttons. I have a separate routine that enables/disables menu-items and toolbar buttons depending on availablilty of data.
It runs at app startup, after which a number of the buttons are disabled. Then when load a file, it is run again, to enable the applicable buttons. So far, so good. However, after the routine is run, the toolbar is not repainted until the mouse moves over it. Even the explicit instruction to Refresh doesn't change that behavior.
Is there a setting / instruction that I'm overlooking?
Version 3 of the Documentation and Compile Utility for Krool's controls has been released here.
MountainMan
While I’m finetuning the implementation of the VBCCR components in my application, I discovered a significant performance issue in one area.
I’m using the following steps to show the user a combo with only unique values:
1. All items are added to a sorted listview
2. Then go through the listview from the top, removing double items
3. Last, the remaining items are added to the dropdown
Using a 1000 records dataset, these were the results:
- Using a sorted Microsoft Common Controls listview, the process takes 25 milliseconds.
- Using a sorted VBCCR listview, the process takes 21030 milliseconds.
- Using a non-sorted VBCCR listview, filling it, setting sorting to true, and then do the rest of the process, takes 138 milliseconds.
The first and third approach broken down:
Microsoft ListView
Fill Listview 8 ms
Remove Doubles 14 ms
Fill Combo 3 ms
VBCCR ListView
Fill Listview 28 ms
Switch to sorted 65 ms
Remove Doubles 40 ms
Fill Combo 5 ms
The ListView basically has all properties set to False, except for Enabled, as it's only used behind the scenes, and therefore doesn't need to be displayed, refreshed, etc.
Note: no further action is expected from my side as I can live with the 138 ms, but I thought to share this to show that different approaches can make a massive difference.
Please Krool help me regarding this point
I followed these steps for VBFlexGrid and everything is working fine on the end user machine.Quote:
Tutorial:
The "Development" machine needs to register the VBCCR17.OCX as usual and use the components for e.g. in a Std-EXE project.
The source project needs to include the Side-by-side resources. (see below)
Then on the "End user" machine you only need the VBCCR17.OCX and the .exe (Std-EXE project) on the same folder.
It will work then without any registration.
However I failed to do so with common controls.
I'll tell you about all the steps I did.
I used the Resource Hacker utility to add the VBCCR17SideBySide.res to the VBFLXGRD14SideBySideAndVisualStyles.res
Once they are compiled in one file I added them to the project.
I placed the VBCCR17.OCX and the VBFLXGRD14.OCX in the .exe folder.
I still have no issue with the VBFLXGRD14 but I'm having error with the VBCCR17
“Component 'VBCCR17. OCX' or one of its dependencies not correctly registered: a file is missing or invalid”
On The "Development" machine, I have no issue
Thank you in advance
Well. The MS ListView will sort kind of "PostMessage" style so you cannot compare it directly.
I think that the VBCCR ListView will sort "directly" is rather a feature than a bug.
You do it correctly that you disable the sort while populating.
I found some spots where maybe a few milliseconds can be saved (e.g. store AddressOf in a variable etc.) When sorting after each insert. However, that fact is neglibile when sorting only once when insertions are finished.
But you can improve by eliminating the duplicates already in the recordset. Also the sorting could be outsourced to the recordset. And ultimate performance would be to make the ListView virtual and fetch the visible viewport data from the recordset only when needed.
VB6sp6
VBCCR 1.7.12
i found a autoresize-bug at the StatusBar-control.
the width of the 2. panel doesnt resize after changing the content.
i have statusbar with 3 panels:
1.panel autoresize=spring
2.panel autoresize=content
3.panel autoresize=content
example:
the 2. panel displays the text "1". after i change the text to "10000" the panel doesnt resize to the new content.
setting the autoresize property to "content" again triggers the 2. panel resize.
changing the width of the statusbar also triggers the 2. panel resize.
the 3. panel always resize correct after changing the content!
I found the bug. The blue marked code fixes the issue of not auto-resizing after changing the panel text.
Update will follow soon...
Code:Friend Property Let FPanelText(ByVal Index As Long, ByVal Value As String)
If StatusBarHandle <> 0 Then
PropShadowPanels(Index).Text = Replace$(Value, vbTab, vbNullString)
Call SetPanelText(Index)
If PropShadowPanels(Index).AutoSize = SbrPanelAutoSizeContent Then Call SetParts
End If
End Property
I agree.
I wouldn't bother if I were you.
The dataset is a collection of a custom class, not a recordset. There actually are multiple, but one example is CProduct, with properties like ID, Name, Supplier. I'm using the described process with a sorted ListView to get a list of Suppliers without duplicates. It seemed the simplest and quickest approach back in the days when I added that feature.
Hi Krool,
Question about the VBFlexgrid:
I switch redraw off, and add 1000 rows with 50 columns. This takes 0.7 seconds.
Then I set sorting to one column (flexSortStringAscending). This takes 10.1 seconds. (With Redraw still off.)
Am I missing some setting, or is the grid sorting simply slow, and am I better of using a temp recordset in memory to sort, and the (re-)populate the grid?
Thanks,
Erwin
the statusbar-panel-autoresize-bug is fixed with OCX v1.7.14!
thx you!
Knowing that the grid could be fast, I investigated further and discovered that it's the SelectionMode setting that is causing the slowness. If I set it to FlexSelectionModeFree the sorting is indeed as fast as you mentioned. However, if I set it to FlexSelectionModeByRow it takes the 10 seconds I mentioned. I'm treating that setting like the Redraw now, off before sorting, and then back on, and performance is good.
One additional question, when a row is selected, the cell in the first column doesn't get the background color even if SelectionMode is set to FlexSelectionModeByRow. Is there a way around that?
Edit: you can ignore the additional question. I realized that it is the FocusRect setting that was not set to None.
I have noticed on the DateTimePicker when CustomFormat is "dd/MM/yyyy hh:mm:ss", that its problematic when you try editing.
AllowUserInput is enabled, the selection of individual values (day, month, year, hour, minute, second) with the mouse selects the whole text.
LOL. :)
It's not a bug but a feature. In fact you are doing a 50 multi-column sort. You just were lucky with the selection mode 'Free' to have not a selection which spans multiple columns.
The code below will help you out to sort only a particular column (for all rows) and it works for every selection mode.
Thats the point for AllowUserInput at all. To allow a text free entry. You need to parse the input accordingly in the "ParseUserInput" event.Code:Dim MyColToSort As Long
MyColToSort = 5 ' or whatever else you have as input
Dim Row1 As Long, Row2 As Long, Col1 As Long, Col2 As Long
With VBFlexGrid1
Row1 = .Row: Row2 = .RowSel: Col1 = .Col: Col2 = .ColSel
.SelectRange Row1, MyColToSort, Row1, MyColToSort ' Ensure single col sort for all rows
.Sort = FlexSortStringAscending
.SelectRange Row1, Col1, Row2, Col2 ' Restore selection
End With
If you don't want this turn AllowUserInput off (=False, which is the default)
OK, then it makes sense that it needed a bit more time to sort. ;)
I'm using version 1.04.0032 of the VBFlexgrid OCX. SelectRange is an unknown property?
Would this approach give the same result as your code example?
Code:With VBFlexGrid1
.SelectionMode = FlexSelectionModeFree
.Redraw = False
.col = iColumn
.Sort = flexSortStringAscending
.SelectionMode = FlexSelectionModeByRow
.Redraw = True
End With
In my grid I have also columns with percentages (e.g. 7.3% and 54.9%) and columns with dimensions (e.g. 7.2cm and 14.6cm or 3.1" and 6.2"). MSFlexgrid sorts these without problems using the Numeric sorts, but the VBFlexGrid doesn't. What is the recommended way to sort these?
Need to test... and if something needs to be enhanced.
Worst case "custom sort option" which raise event.
Edit: you may store the percentage as number only and use .ColFormat property to add the "%" char as formatting. Thus the sort would work as immediate solution.
Btw. you can sort also using the cell property
This way you don't need to bother change row col etc. and to restore it..Code:.Cell(FlexCellSort, Row1, Col1, Row2, Col2) = flexSortStringAscending
Edit: please continue in the VBFlexGrid thread!
I'm sorry about that.
I'm not dissatisfied, I'm just saying that the control is very good.It is suggested to add some transparent functions, because 99% of people do not have the ability to modify it at all.After all, all VB.NET controls are transparent.Today, 23 years later, we are developing a basic control with some new elements. Such as a transparent background or translucent mask.