Hallo Liebe Community,
ich möchte meinen Cursor, meine Mouse Position innerhalb des Fensters ändern.
Bis hab ich herausgefunden an welcher Position sich einige Controls befinden. Nur wenn ich dann mit gewissen Standard Sachen versuche die Cursor Position zu ändern bspw.
System.Windows.Forms.Cursor.Position = meineNeuePosition
Ändert er es auf dem gesamten Bildschirm, ich möchte mich gerne nur innerhalb des Fenster bewegen. Wenn ich versuche die Position des Fenster's zu ermitteln, um das ganze dann zu addieren, bekomme ich die Werte 0,0.
Bringt mir nichts. Hat jemand eine Idee, wie ich das ganze umsetzen kann.
Grüße
Hallo,
die Methoden PointToScreen und ScreenToPoint sind das was du suchst.
vg
Wenn's zum weinen nicht reicht, lach drüber!
Hallo,
also PointToScreen kenn ich ScreenToPoint nicht, nur PointFromScreen.
Mit beiden konnte ich bisher nicht das gewünschte Ergebnis erreichen, vllt hab ich was falsch gemacht.
Aktuell versuch ich mit
With Application.Current.MainWindow
MessageBox.Show(.Left & " " .Top)
End With
Die aktuelle Position des Fenster's zu bekommen, jedoch wirft das nicht immer optimale Ergebnisse.
Gruß
Ach die mein ich doch 😉 Du kannst nur die Koordinaten innerhalb eines Fensters oder die absoluten Koordinaten ermitteln..
Wieso verwendest du eigentlich System.Windows.Forms.Cursor.Position, sonst ist doch deine Frage eher ins Winforms forum einzuordnen ... vg
Wenn's zum weinen nicht reicht, lach drüber!
Naja darauf wurde halt verwiesen, in diversen Foren Einträgen.
Ich versuch das mal nochmal ordentlich zu erklären, ich möchte in WPF :
In meinem Fenster den Cursor verschieben, der Sinn dahinter ich möchte mir via Button
ein neues ListBoxItem erstellen und auf dieses Item meinen Cursor legen.
PointFromScreen -
Konvertiert einen in Bildschirmkoordinaten angegebenen Point in einen Point, der das aktuelle Koordinatensystem des Visual darstellt.
ScreenToPoint -
Rechnet die Position des angegebenen Clientpunkts in Bildschirmkoordinaten um
Helfen mir dabei eigentlich nicht wirklich, weil sich selbst dann der Cursor nur innerhalb des Bildschirm verschiebt, nicht innerhalb des Fensters
Grüße
😉 Ich hab das schon verstanden, ich bin nur davon ausgegangen, dass du weißt wie das in Windows funktioniert...also versuch ich es etwas genauer zu erklären...
Es gibt in WPF keine mit bekannte möglichkeit die Cursorposition zu setzen. Du solltest dir besser ne external deklaration (dllimport) für den WinApi-Aufruf SetCursorPos schreiben ... das ist eine zeile.
Diese Methode arbeitet, wenn es kein gültiges Fensterhandle bekommt, mit absoluten koordinaten.
Du bekommst mit PointToScreen(0,0) bekommst du vom UIElement, an dem du diese methode aufrufst die absoluten koordinaten. Da musst du nicht mal addieren wenn du dein listitem in der hand hast... zb -> MainWindow.PointToScreen(0,0) -> 120, 246 --- ausser es ist maximized, dann bekommst du die minimalkoordinaten deines aktuellen Monitors, wenn du nur einen hast -> 0,0.
diese koordinaten kannst du dann als ausgangspunkt für deine neue mausposition verwenden..
MainWindow-> 200,200
Button im MainWindow -> 10,10
button.PointToScreen(0,0) -> 210,210
vg
Wenn's zum weinen nicht reicht, lach drüber!
1.) Ich weiß hab ich schon gemacht : Private Declare Function SetCursorPos Lib "user32" (ByVal X As Integer, ByVal Y As Integer) As Boolean
Hätte ich vllt dazu sagen sollen, sorry schreib selten Foren Beiträge 😐
Ich teste das ganze mal fix, danke.
Dim ListBoxP As Point = ListBoxMain.PointToScreen(New Point(0, 0))
Dim MainWindowP As Point = Application.Current.MainWindow.PointToScreen(New Point(0, 0))
Dim MainPoint As Point = New Point(ListBoxP.X + MainWindowP.X, ListBoxP.Y + MainWindowP.Y)
MessageBox.Show("FirstP X : " & ListBoxP.X & " " & "FirstP Y : " & ListBoxP.Y & " " & "SecondP X : " & MainWindowP.X & " " & "Second P: " & MainWindowP.Y)
MsgBox(MainPoint.X & " " & MainPoint.Y)
SetCursorPos(MainPoint.X, MainPoint.Y)
Hat nicht das gewünsche Ergebnis gebracht.
Gruß
Edit : Bei dem Roten Kreis war ca mein Cursor
Fast großer...fast 😉
ListBoxP.PointToScreen reicht aus...dann hast du die koordinaten des controls ..rechnest noch 1,1 drauf und dann is dein cursor da wo er hin soll...lies dir noch mal meinen 3. punkt genau durch
Wenn's zum weinen nicht reicht, lach drüber!
Ja, gut stimmt reicht aus.
Aber wie krieg ich das jetzt zu einem Item der ListBox nach dem gleichen Prinzip?
Edit : Bzw geht das überhaupt?
Gruß
gar nicht oder nur über einen enormen aufwand...ui-tests proggen ist sehr sehr aufwändig und nicht unbedingt zuverlässig...:) deshalb trennt man die applikationslogik von der oberfläche. mvvm ist hier das zauberwort. da kannst du nämlich per unittest deine funktionen ausführen.
vg
Wenn's zum weinen nicht reicht, lach drüber!
Naja das Ziel soll sein beim Hinzufügen eines ListBoxItems den Cursor auf das aktuell hinzugefügte Item zu setzen, da führt kein Weg dran vorbei. So ist die Vorgabe 😐
Hat sich bestimmt son vollprofi bei euch ausgedacht, ohne das böse zu meinen, unwissenheit kann manchmal eine menge zeit und geld und ärger bedeuten 😉 vielleicht wäre es an dieser stelle sinnvoller darüber nachzudenken, dieses ominöse mvvm mal etwas genauer zu betrachten und dann total eeuphorisch zum verantwortlichen zu rennen und ihm zu sagen dass man diese testerei automatisieren kann -> nunit und buildserver lassen grüßen..das kann man in einem bruchteil der zeit programmieren und läuft ca 10000 mal schneller als n programm zu starten und dann testen zu lassen.
wpf bietet übrigens eine schnittstelle für automated-ui-tests...habs selbst noch nie benutzt, da kann ich dir nur das nachlesen empfehlen.
vg
Wenn's zum weinen nicht reicht, lach drüber!
Also von der Idee eher verabschieden 😮
Erstmal danke für die ganze Hilfe 😃
Kein Ding...viel erfolg noch
Wenn's zum weinen nicht reicht, lach drüber!
Moinsen,
ich bin jetzt soweit das ich den Cursor auf das zuletzt hinzugefügt Item setzen kann.
Private Function HöheDerItems() As Integer
Dim Höhe As Integer = 0
Dim iCount As Integer = 0
Do While iCount <= ListBox_Test.Items.Count - 1
Dim Item = CType(ListBox_Test.ItemContainerGenerator.ContainerFromItem(ListBox_Test.Items.Item(iCount)), ListBoxItem)
If iCount = ListBox_Test.Items.Count - 1 Then
Höhe += Item.ActualHeight / 2
Else
Höhe += Item.ActualHeight
End If
iCount = iCount + 1
Loop
Return Höhe
End Function
ListBox_Test.Items.Add("AA")
ListBox_Test.SelectedIndex = ListBox_Test.Items.Count - 1
ListBox_Test.Focus()
Dim c As Point = ListBox_Test.PointToScreen(New Point(0, 0))
Dim Breite As Integer = ListBox_Test.ActualWidth / 2
Dim Höhe As Integer = 10
MsgBox(Breite.ToString)
c.X = c.X + Breite
c.Y = c.Y + HöheDerItems()
SetCursorPos(c.X, c.Y)
Brauch eigentlich nur noch ein Event für das ListBoxItem, tu mich da gerade noch schwer/dumm.
Hrhr du gibst nicht auf was 😃
Was machst du denn wenn jemand das DataTemplate für dein ListboxItem anpasst oder die Transformationsmatrizen manipuliert? Dann musst du den Wert deiner geratenen Höhe mit anpassen 😃
Was für ein Event meinst du ? für den Mausklick ? 😃 WinAPI -> SendMessage
Wenn's zum weinen nicht reicht, lach drüber!
Aufgeben wäre zu einfach 😕
Also aktuell hab ich es hinbekommen hier mal der Code :
Class MainWindow
Private WithEvents CurrentItem As ListBoxItem
Private _TextBox As TextBox
Private Function HeightOfItems() As Integer
Dim _Height As Integer = 0
Dim iCount As Integer = 0
Do While iCount <= ListBox_Main.Items.Count - 1
Dim Item = CType(ListBox_Main.ItemContainerGenerator.ContainerFromItem(ListBox_Main.Items.Item(iCount)), ListBoxItem)
' --- Das letzte Item / Neu hinzugefügt --- '
If iCount = ListBox_Main.Items.Count - 1 Then
_Height += Item.ActualHeight / 2
Else
_Height += Item.ActualHeight
End If
iCount = iCount + 1
Loop
Return _Height
End Function
Private Declare Function SetCursorPos Lib "user32" (ByVal X As Integer, ByVal Y As Integer) As Boolean
Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
_TextBox = New TextBox
_TextBox.Width = 200
Dim _Object As Object = _TextBox
ListBox_Main.Items.Add(_Object)
ListBox_Main.SelectedIndex = ListBox_Main.Items.Count - 1
ListBox_Main.Focus()
MsgBox(ListBox_Main.SelectedIndex)
Dim _Width As Integer = ListBox_Main.ActualWidth / 2
Dim _ListBox_StartPoint As Point = ListBox_Main.PointToScreen(New Point(0, 0))
SetCursorPos(_ListBox_StartPoint.X + _Width, _ListBox_StartPoint.Y + HeightOfItems())
Dim _CurrentItem = CType(ListBox_Main.ItemContainerGenerator.ContainerFromItem(ListBox_Main.Items.Item(ListBox_Main.Items.Count - 1)), ListBoxItem)
CurrentItem = _CurrentItem
End Sub
Private Sub CurrentItem_MouseLeave(sender As Object, e As System.Windows.Input.MouseEventArgs) Handles CurrentItem.MouseLeave
' --- TextBox auf Inhalt prüfen --- '
If _TextBox.Text = "" Then
ListBox_Main.Items.RemoveAt(ListBox_Main.Items.Count - 1)
End If
End Sub
End Class
Einige Fälle sind natürlich noch nicht berücksichtigt, an sich ist die ListBox nur dafür da glaube ich eine IP - Adresse einzutragen bzw irgendein Text einzutragen, da kann nicht soviel manipuliert werden.
Findest du der Wert ist geraten? Ich nehme die exakte Position wo die ListBox beginnt, von dort aus hol ich mir beim Hinzufügen eines Eintrages die aktuelle Breite der ListBox.
Nehme davon die Hälfte, Platziere dort den Cursor.
Und die Höhe hol ich mir ja immer die aktuelle des Items. Alles ohne Raten 😄
Sollte doch klappen?
Grüße
Natürlich ist das geraten 😉
Also ums mal zu erklären : innerhalb eines ItemsControls kann sich jedes element aufgrund des verwendeten Templates von einander unterscheiden du kannst triggern animieren und komische sachen machen da ändert sich ständig die größe ... und das ganze noch asynchron 😃 Ich sach ja schau dir das mvvm pattern mal an...das ist so primitiv da kann man nicht viel falsch machen ...
wert - binding - control
(Name) {BINDING ... } (TextBox)
außer man versucht quick and dirty lösungen wie deine zu machen 😃 geht ne weile gut...führt aber schlussendlich zu problemen die du heute noch nicht kennst.
Das was du da versuchst kann man mit ca 10 Zeilen Code umsetzen...ohne rechnerei
Wenn's zum weinen nicht reicht, lach drüber!