FolderBrowserDialog - SelectedPath in sichtbaren Bereich anzeigen
Hallo,
Wir haben beim FolderBrowserDialog mit vb.net über SelectedPath einen Netzwerkpfad voreingestellt.
Dieser ist leider nie im sichtbaren Bereich des Dialoges.
Der Dialog fängt immer oben mit Desktop an.
Man muss immer weit herunterscrollen um zum vorausgewählten Ordner zu kommen.
Kennt jemand einen Trick wie man den vorausgewählten Ordner automatisch zentriert in den sichtbaren Bereich der Liste bekommt?
Der Standard .net FolderBrowserDialog hat so gut wie keine Einstellungsmöglichkeiten.
Noch dazu würde ich gerne auch die Unterordner sofort sehen können, FALLS es in dem vorausgewählten Ordner überhaupt Unterordner gibt.
Also den TreeView im SelectedPath sofort komplett aufklappen.
Weiß jemand wie man das implementiert?
Und warum gibt es das nicht schon seit Jahren standardmäßig?
Das kann doch jeder mal gebrauchen.
Gruß,
Rene
Wir haben beim FolderBrowserDialog mit vb.net über SelectedPath einen Netzwerkpfad voreingestellt.
Dieser ist leider nie im sichtbaren Bereich des Dialoges.
Der Dialog fängt immer oben mit Desktop an.
Man muss immer weit herunterscrollen um zum vorausgewählten Ordner zu kommen.
Kennt jemand einen Trick wie man den vorausgewählten Ordner automatisch zentriert in den sichtbaren Bereich der Liste bekommt?
Der Standard .net FolderBrowserDialog hat so gut wie keine Einstellungsmöglichkeiten.
Noch dazu würde ich gerne auch die Unterordner sofort sehen können, FALLS es in dem vorausgewählten Ordner überhaupt Unterordner gibt.
Also den TreeView im SelectedPath sofort komplett aufklappen.
Weiß jemand wie man das implementiert?
Und warum gibt es das nicht schon seit Jahren standardmäßig?
Das kann doch jeder mal gebrauchen.
Gruß,
Rene
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 282543
Url: https://administrator.de/forum/folderbrowserdialog-selectedpath-in-sichtbaren-bereich-anzeigen-282543.html
Ausgedruckt am: 14.04.2025 um 19:04 Uhr
6 Kommentare
Neuester Kommentar
Hi,
daran sind schon andere verzweifelt. Ich selbst habe uns dafür eigene Controls entworfen. Andere greifen auf vorhandene im Web zurück.
Such mal bei Google. da kommen z.B.
http://stackoverflow.com/questions/6942150/why-folderbrowserdialog-dial ...
http://stackoverflow.com/questions/12429477/folderbrowserdialog-showing ...
http://stackoverflow.com/questions/12429477/folderbrowserdialog-showing ...
Keine Ahnung, ob die fruchten. Nur so als Hinweis.
E.
daran sind schon andere verzweifelt. Ich selbst habe uns dafür eigene Controls entworfen. Andere greifen auf vorhandene im Web zurück.
Such mal bei Google. da kommen z.B.
http://stackoverflow.com/questions/6942150/why-folderbrowserdialog-dial ...
http://stackoverflow.com/questions/12429477/folderbrowserdialog-showing ...
http://stackoverflow.com/questions/12429477/folderbrowserdialog-showing ...
Keine Ahnung, ob die fruchten. Nur so als Hinweis.
E.
Hallo René,
das lässt sich mit einer kleinen AutoIt-EXE machen:
Den Pfad zum gewünschten Ordner musst du in Zeile 2 anpassen. Siehe dazu:
https://www.autoitscript.com/autoit3/docs/functions/ControlTreeView.htm
Und dann so in deine Anwendung einbauen:
Das ganze lässt sich natürlich mit etwas Aufwand und der Win32-API nachbauen und direkt in VB.Net einbauen.
Grüße Uwe
das lässt sich mit einer kleinen AutoIt-EXE machen:
1
2
3
4
5
2
3
4
5
#NoTrayIcon
$path = "Desktop|Computer|Daten (D:)|Eigene Bilder"
$hwnd = WinWaitActive("Ordner suchen",10)
ControlTreeView($hwnd,"","[CLASS:SysTreeView32; INSTANCE:1]","Select",$path)
ControlTreeView($hwnd,"","[CLASS:SysTreeView32; INSTANCE:1]","Expand",$path)
https://www.autoitscript.com/autoit3/docs/functions/ControlTreeView.htm
Und dann so in deine Anwendung einbauen:
1
2
3
4
5
6
7
2
3
4
5
6
7
Dim f As New FolderBrowserDialog
With f
.RootFolder = Environment.SpecialFolder.Desktop
.SelectedPath = "D:\Bilder"
Process.Start("C:\script.exe")
.ShowDialog()
End With
Grüße Uwe
Das ganze lässt sich natürlich mit etwas Aufwand und der Win32-API nachbauen und direkt in VB.Net einbauen.
So habe mir das gerade mal in dieser Hinsicht angeschaut und dir was mit VB.Net zusammengecodet. Läuft hier testweise unter Windows 7 x64 und Windows 10 x64 :Unter Windows 10 wurde das Verhalten aber schon behoben. Was natürlich verwundert ist das es ja bereits eine MSG_ID für genau das Verhalten gibt was man eigentlich erwartet, nämlich TVM_ENSUREVISIBLE das den selektierten Knoten ins Sichtfeld scrollt. Das macht mein Code in diesem Fall, und zusätzlich wird der Knoten noch expanded wenn es Unterordner gibt.
Das Beispiel besteht jetzt nur aus einer Form mit einem einzigen Button (Name: btnOpenFolderBrowser)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
Imports System.Runtime.InteropServices
Public Class Form1
WithEvents tm As New Timer
Const TV_FIRST As Integer = &H1100
Const TVGN_ROOT As Integer = &H0
Const TVGN_NEXT As Integer = &H1
Const TVGN_CHILD As Integer = &H4
Const TVGN_FIRSTVISIBLE As Integer = &H5
Const TVGN_NEXTVISIBLE As Integer = &H6
Const TVGN_CARET As Integer = &H9
Const TVM_SELECTITEM As Integer = (TV_FIRST + 11)
Const TVM_GETNEXTITEM As Integer = (TV_FIRST + 10)
Const TVM_GETITEM As Integer = (TV_FIRST + 12)
Const TVM_ENSUREVISIBLE As Long = (TV_FIRST + 20)
Const TVM_EXPAND As Long = (TV_FIRST + 2)
Const TVE_EXPAND As Integer = &H2
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Public Shared Function FindWindowEx(ByVal hWndParent As IntPtr, ByVal hWndChildAfter As IntPtr, ByVal lpszClass As String, ByVal lpszWindow As String) As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Public Shared Function SendMessage(hWnd As IntPtr, Msg As UInt32, wParam As IntPtr, lParam As IntPtr) As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Public Shared Function GetWindowThreadProcessId(hwnd As IntPtr, lpdwProcessId As IntPtr) As IntPtr
End Function
Private Sub btnOpenFolderBrowser_Click(sender As System.Object, e As System.EventArgs) Handles btnOpenFolderBrowser.Click
Dim fBrowser As New FolderBrowserDialog
tm.Interval = 200
With fBrowser
.SelectedPath = "C:\Windows\system32"
tm.Start()
.ShowDialog()
tm.Stop()
End With
End Sub
Private Sub tm_Tick(sender As Object, e As System.EventArgs) Handles tm.Tick
'Get TreeView Control on Dialog
Dim controlHwnd As IntPtr = getTVHandle(IntPtr.Zero)
If (controlHwnd <> 0) Then
'Get selected node
Dim selectedNode As IntPtr = SendMessage(controlHwnd, TVM_GETNEXTITEM, TVGN_CARET, IntPtr.Zero)
'scroll selected item into view
SendMessage(controlHwnd, TVM_ENSUREVISIBLE, IntPtr.Zero, selectedNode)
'expand node
SendMessage(controlHwnd, TVM_EXPAND, TVE_EXPAND, selectedNode)
'stop timer
tm.Stop()
End If
End Sub
Function getTVHandle(handle As IntPtr) As IntPtr
Dim parent As IntPtr, returnTVHandle As Boolean
If handle = IntPtr.Zero Then
parent = FindWindow("#32770", Nothing)
If Not isFromSameThread(parent) Then
Return getTVHandle(parent)
Else
returnTVHandle = True
End If
Else
parent = FindWindowEx(IntPtr.Zero, handle, "#32770", Nothing)
If Not isFromSameThread(parent) Then
Return getTVHandle(parent)
Else
returnTVHandle = True
End If
End If
If returnTVHandle Then
'Get Control handle
Dim subWin As IntPtr = FindWindowEx(parent, IntPtr.Zero, "SHBrowseForFolder ShellNameSpace Control", Nothing)
Dim controlHwnd As IntPtr = FindWindowEx(subWin, IntPtr.Zero, "SysTreeView32", Nothing)
Return controlHwnd
End If
End Function
Function isFromSameThread(handle As IntPtr) As Boolean
Dim cID As Integer = AppDomain.GetCurrentThreadId()
Dim fID As Integer = GetWindowThreadProcessId(handle, IntPtr.Zero)
Return (cID = fID)
End Function
End Class
Hier noch die kompilierte EXE zum testen, sie öffnet den FolderBrowser im Beispiel mit dem initialen Pfad C:\Windows\system32 mit aufgeklappten Unterordnern:
FolderBrowserWithScrollIntoView_282543.exe
Grüße Uwe
Falls der Beitrag gefällt, seid so nett und unterstützt mich durch eine kleine Spende / If you like my contribution please support me and donate
Zitat von @Rene1976:
Wie ich auch schon gelesen habe, gibt es bei unterschiedlichen Windows Versionen bei anderen Versuchen Probleme.
Ich kann dir auch sagen warum, weil unter XP der Dialog noch anderst aufgebaut ist.Wie ich auch schon gelesen habe, gibt es bei unterschiedlichen Windows Versionen bei anderen Versuchen Probleme.
In den neueren Dialogen ist das TreeView Control verschachtelter im Dialog untergebracht (Unterfenster, kannst du mit Tools wie Spy++ sehr schön sehen), was unter XP noch nicht der Fall ist, aber das ließe sich noch in dem Code unterbringen wenn das erforderlich ist.
NACHTRAG: Unter XP SP3 wurde der Code ebenfalls erfolgreich getestet.