Benutzer mit den meisten Antworten
Usercontrol verkleinern Vergößern in gedrehtem zustand

Frage
-
Hallo Welt,
wie immer DANKE an alle die mir helfen und euch auch ein Gutes Neues Jahr
Ich habe folgendes USercontrol
<Canvas >
<Border x:Name="boHZB" Width="400" Height="60" RenderTransformOrigin="0.5,0.5" MaxWidth="800" MinWidth="50" BorderThickness="1,1,1,1" BorderBrush="Black" Canvas.Left="0" Canvas.Top="0">
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="0" />
<TranslateTransform/>
</TransformGroup>
</Border.RenderTransform>
<Grid x:Name="hzbgrid" Background="DodgerBlue" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Panel.ZIndex="0">
<Image x:Name="imgselbstklebend" Source="/imghzb/lf_sk_quer.png" Height="{Binding Height, ElementName=hzbgrid}" Width="{Binding Width, ElementName=hzbgrid}" Stretch="Fill" Margin="5,5,5,5"/>
<Label x:Name="lblBeschriftung" MinWidth="160" Content="Bernhard" HorizontalContentAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Top" Panel.ZIndex="2" />
<Label x:Name="lblLaenge" MinWidth="160" Content="{Binding Width, ElementName=boHZB}" HorizontalContentAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Bottom" Panel.ZIndex="2" />
<Ellipse x:Name="pkilo" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="-4,-4,0,0" Panel.ZIndex="2" Cursor="SizeNESW" Visibility="Visible"/>
<Ellipse x:Name="pkimo" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="center" VerticalAlignment="Top" Margin="-4,-4,0,0" Panel.ZIndex="2" Cursor="ScrollN" Visibility="Visible" ToolTip="rechte maustaste kopiert die Heizbahn"/>
<Ellipse x:Name="pkiro" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,-4,-4,0" Panel.ZIndex="2" Cursor="SizeNWSE" Visibility="Visible"/>
<Ellipse x:Name="pkirm" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,-4,-4,0" Panel.ZIndex="21" Cursor="SizeWE" Visibility="Visible"/>
<Ellipse x:Name="pkimi" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="center" VerticalAlignment="center" Margin="0,0,0,0" Panel.ZIndex="2" Cursor="ScrollAll" Visibility="Visible"/>
<Ellipse x:Name="pkilm" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="-4,-4,0,0" Panel.ZIndex="2" Cursor="SizeWE" Visibility="Visible"/>
<Ellipse x:Name="pkilu" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="-4,0,0,-4" Panel.ZIndex="2" Cursor="SizeNWSE" Visibility="Visible"/>
<Ellipse x:Name="pkium" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="center" VerticalAlignment="Bottom" Margin="-4,0,0,-4" Panel.ZIndex="2" Cursor="ScrollS" Visibility="Visible"/>
<Ellipse x:Name="pkiru" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,-4,-4" Panel.ZIndex="2" Cursor="SizeNESW" Visibility="Visible"/>
</Grid>
</Border>
</Canvas>Die PKI.. sind Anfangspunkte für die Maus um das Control zu vergrößern und zu verkleinern.
Jetzt habe ich folgendes Problem
Sobald ich eine Angel von > 0 habe passiert beim verkleinern und vergrößern (immer Wert 10) folgendes:
Dass usercontrol verkleinert sich an beiden Seiten gleichzeiig. Ich möchte jedoch dass es sich nur an der seite verkleinert an der ich den Anfasspunkte verwende. und nicht an beiden seien gleichzeitig.
Die Größe der boHZB wird durch die Änderung der Width Variable gesetzt, die durch Codebehind auslöse.
Wer mir weiterhelfen kann - VIELEN DANK
wer nicht - trotzden danke das ihr reingeschaut habt
Mein Erklärung:
Durch die Verkleinerung verändert sich der ABSTAND Canvas.TOP den ich ausgleichen möchte. Nehmen wir mal an ich verkleinere um 10 Pixel. Dann ist der Auszugleichende Wert ja nicht 10 Pixel sondern die Anzahl Pixel bezogen auf die Drehung unter Berücksichtigung der Verkleinerung. Die TransformWerte verändern sich entsprechen. Nehme ich Drehung 90 dann ist dass kein Problem, da hier die Verkleinerung 1:1 mit Canvas.TOP ausgeglichen werden kann.
Nach dem Motte 5 weg und jetzt mit 2.345454 ausgleichen
Ich müsste für jede Drehpunkt 1....180 jeweils festhalten, dass wären dann 178 Werte nach dem Motto:
bei Angel = 1 Wert Xy, bei Angel =2 Wert xy, bei Angel =3 Wert xyDass muss man doch über ein Formel berechnen können :-)
Bernhard Meyer Danke
- Bearbeitet Bernhard Meyer Freitag, 7. Januar 2022 12:23 bild
Antworten
-
Hi Bernhard,
hier mal eine andere Version von mir:<UserControl x:Class="Window108UC1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfControlLibrary1" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" x:Name="uc"> <Canvas x:Name="cv" Background="White"> <Border x:Name="boHZB" Width="400" Height="60" RenderTransformOrigin="0.5,0.5" MaxWidth="800" MinWidth="50" BorderThickness="1,1,1,1" BorderBrush="Black" Canvas.Left="0" Canvas.Top="0"> <Border.RenderTransform> <TransformGroup> <RotateTransform Angle="{Binding Angle}" CenterX="{Binding RotatePositionInMoveObject.X}" CenterY="{Binding RotatePositionInMoveObject.Y}"/> <TranslateTransform X="{Binding TranslateVector.X}" Y="{Binding TranslateVector.Y}"/> </TransformGroup> </Border.RenderTransform> <Grid Background="DodgerBlue" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Panel.ZIndex="0" Margin="0,0,-0,0"> <!--<Image x:Name="imgselbstklebend" Source="/imghzb/lf_sk_quer.png" Height="{Binding Height, ElementName=hzbgrid}" Width="{Binding Width, ElementName=hzbgrid}" Stretch="Fill" Margin="5,5,5,5"/>--> <Label x:Name="lblBeschriftung" MinWidth="160" Content="Bernhard" HorizontalContentAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Top" Panel.ZIndex="2" /> <Label x:Name="lblLaenge" MinWidth="160" Content="{Binding Width, ElementName=boHZB}" HorizontalContentAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Bottom" Panel.ZIndex="2" /> <Ellipse x:Name="pkilo" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="-4,-4,0,0" Panel.ZIndex="2" Cursor="SizeNESW" Visibility="Visible"/> <Ellipse x:Name="pkimo" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="center" VerticalAlignment="Top" Margin="-4,-4,0,0" Panel.ZIndex="2" Cursor="ScrollN" Visibility="Visible" ToolTip="rechte maustaste kopiert die Heizbahn"/> <Ellipse x:Name="pkiro" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,-4,-4,0" Panel.ZIndex="2" Cursor="SizeNWSE" Visibility="Visible"/> <Ellipse x:Name="pkirm" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,-4,-4,0" Panel.ZIndex="21" Cursor="SizeWE" Visibility="Visible"/> <Ellipse x:Name="pkimi" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="center" VerticalAlignment="center" Margin="0,0,0,0" Panel.ZIndex="2" Cursor="ScrollAll" Visibility="Visible"/> <Ellipse x:Name="pkilm" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="-4,-4,0,0" Panel.ZIndex="2" Cursor="SizeWE" Visibility="Visible"/> <Ellipse x:Name="pkilu" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="-4,0,0,-4" Panel.ZIndex="2" Cursor="SizeNWSE" Visibility="Visible"/> <Ellipse x:Name="pkium" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="center" VerticalAlignment="Bottom" Margin="-4,0,0,-4" Panel.ZIndex="2" Cursor="ScrollS" Visibility="Visible"/> <Ellipse x:Name="pkiru" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,-4,-4" Panel.ZIndex="2" Cursor="SizeNESW" Visibility="Visible"/> </Grid> </Border> </Canvas> </UserControl>
Dazu der CodeBehind:
Imports System.ComponentModel Imports System.Runtime.CompilerServices Public Class Window108UC1 Implements INotifyPropertyChanged Public Sub New() ' This call is required by the designer. InitializeComponent() ' Add any initialization after the InitializeComponent() call. Me.DataContext = Me End Sub Private MoveType As MoveTypeEnum Private Container As FrameworkElement Private MoveObject As FrameworkElement Private StartPositionInContainer As Vector Public Property RotatePositionInMoveObject As Point Private MoveObjectSizeOld As Size Private TranslateVectorOld As Vector Public Property TranslateVector As Vector Private AngleOld As Double Public Property Angle As Double Private Sub pkirm_PreviewMouseDown(sender As Object, e As MouseButtonEventArgs) Handles pkirm.PreviewMouseDown MoveType = MoveTypeEnum.WidthLeft CacheValues(sender, e) End Sub Private Sub pkium_PreviewMouseDown(sender As Object, e As MouseButtonEventArgs) Handles pkium.PreviewMouseDown MoveType = MoveTypeEnum.HeigthBottom CacheValues(sender, e) End Sub Private Sub pkimi_PreviewMouseDown(sender As Object, e As MouseButtonEventArgs) Handles pkimi.PreviewMouseDown MoveType = MoveTypeEnum.Center CacheValues(sender, e) End Sub Private Sub pkiru_PreviewMouseDown(sender As Object, e As MouseButtonEventArgs) Handles pkiru.PreviewMouseDown MoveType = MoveTypeEnum.RotateBottomRight CacheValues(sender, e) End Sub Private Sub CacheValues(sender As Object, e As MouseButtonEventArgs) Container = cv MoveObject = boHZB AngleOld = Angle TranslateVectorOld = TranslateVector MoveObjectSizeOld = New Size(MoveObject.ActualWidth, MoveObject.ActualHeight) StartPositionInContainer = e.GetPosition(Container).ToVector RotatePositionInMoveObject = New Point(-MoveObject.Width / 2, -MoveObject.Height / 2) End Sub Private Sub uc_PreviewMouseMove(sender As Object, e As MouseEventArgs) Handles uc.PreviewMouseMove If MoveObject Is Nothing OrElse e.LeftButton <> MouseButtonState.Pressed Then MoveType = MoveTypeEnum.None Exit Sub End If Dim diffVector = New Vector(e.GetPosition(Container).X - StartPositionInContainer.X, e.GetPosition(Container).Y - StartPositionInContainer.Y) Select Case MoveType Case MoveTypeEnum.WidthLeft MoveObject.Width = MoveObjectSizeOld.Width + diffVector.X RotatePositionInMoveObject = New Point(-MoveObject.Width / 2, -MoveObject.Height / 2) OnPropChanged(NameOf(RotatePositionInMoveObject)) Case MoveTypeEnum.HeigthBottom MoveObject.Height = MoveObjectSizeOld.Height + diffVector.Y RotatePositionInMoveObject = New Point(-MoveObject.Width / 2, -MoveObject.Height / 2) OnPropChanged(NameOf(RotatePositionInMoveObject)) Case MoveTypeEnum.Center TranslateVector = Vector.Subtract(Vector.Add(TranslateVectorOld, e.GetPosition(Container).ToVector), StartPositionInContainer) OnPropChanged(NameOf(TranslateVector)) Case MoveTypeEnum.RotateBottomRight Dim v1 = Vector.Subtract(StartPositionInContainer, TranslateVectorOld) Dim v2 = Vector.Subtract(New Vector(e.GetPosition(Container).X, e.GetPosition(Container).Y), TranslateVectorOld) Angle = AngleOld + Vector.AngleBetween(v1, v2) OnPropChanged(NameOf(Angle)) RotatePositionInMoveObject = New Point(-MoveObject.Width / 2, -MoveObject.Height / 2) OnPropChanged(NameOf(RotatePositionInMoveObject)) End Select e.Handled = True End Sub Private Sub uc_PreviewMouseUp(sender As Object, e As MouseButtonEventArgs) Handles uc.PreviewMouseUp MoveType = MoveTypeEnum.None End Sub Enum MoveTypeEnum None WidthLeft HeigthBottom Center RotateBottomRight End Enum Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged Private Sub OnPropChanged(<CallerMemberName> Optional propName As String = "") RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propName)) End Sub End Class Public Module Extensions <Extension()> Public Function ToVector(ByVal p As Point) As Vector Return New Vector(p.X, p.Y) End Function End Module
Und das sieht dann so aus:
--
Best Regards / Viele Grüße
Peter Fleischer (former MVP for Developer Technologies)
Homepage, Tipps, Tricks- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Moderator Montag, 17. Januar 2022 13:29
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Moderator Freitag, 28. Januar 2022 11:21
Alle Antworten
-
Hi Bernhard,
anhand deiner Beschreibung vermute ich, dass in deinem Code die Methoden der Math-Klasse falsch aufgerufen werden. Zeig mal einen Codeschnipsel.--
Best Regards / Viele Grüße
Peter Fleischer (former MVP for Developer Technologies)
Homepage, Tipps, Tricks -
Hallo Peter - danke für deinen Hilfe
'Hier greif ich die mauskooridinaten ab
Private Sub pkirm_PreviewMouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs) Handles pkirm.PreviewMouseLeftButtonDown
_mausPosition.X = e.GetPosition(Parent).X
'****************************************
_hzbPosition.X = (_mausPosition.X - boHZB.Width) 'hier hol ich mir den Pos laut Laenge
_hzbPosition.Y = (_mausPosition.Y - (boHZB.Height/2)) ' dann habe ich den mittleren Punkt
_hzbStartLaenge = boHZB.Width
'****************************************
pkirm.CaptureMouse()
End Sub
Private Sub pkirm_PreviewMouseMove(sender As Object, e As MouseEventArgs) Handles pkirm.PreviewMouseMove
If e.LeftButton = MouseButtonState.Pressed Then
Dim iDiff As Point ' Differnezberechnung
Dim iDiffWert As Point ' der wert der Veränderung
Dim iaktPos As Thickness = hzbCanvasPosition ' Hier dird die CanvasPosition von boHZB abgefargt
Dim iaktPos2 As Thickness = iaktPos
_mausMovePosition.X = e.GetPosition(Parent).X
_mausMovePosition.Y = e.GetPosition(Parent).Y
'*** laenge auf 10 aufrunden
iDiff.X = (_mausMovePosition.X - _hzbPosition.X)
iDiff.X = CInt(Math.Round(iDiff.X / _HzbLaengenAufrundung) * _HzbLaengenAufrundung)
' das mach ich weil ich nur 10er Schritte laufen lassen will
'Jetzt kommt eine max und min Längen Pürfung
If iDiff.X > MaxWidth Then iDiff.X = MaxWidth
If iDiff.X < MinWidth Then iDiff.X = MinWidth
Laenge = iDiff.X ' Hier wird die Länge an ein Property übergeben, dass die boHZB Width beeinflusst
iDiffWert.X = _hzbStartLaenge - iDiff.X ' Festhalten Wert der änderung laut mousedown
'**********
If Drehung > 0 And iDiffWert.X <> 0 Then ' hier wird geprüft ob angle <> 0 ist
Drehung ist Property und stetzt das TransformLayout
'boHZB.RenderTransform = New RotateTransform(value)
' Hier fange ich die Veränderung der 10 (5 auf beiden Seiten ab)
' da dadurch Left um 5 verschoben wird addiere ich wieder 5
iaktPos.Left += (iDiffWert.X / 2) 'iDiffWert entspricht den 10
' jetzt aktualisiere ich die CanvasPosition
hzbCanvasPosition = iaktPos
End If
'***********************
'damit ich beim MouseMove die Werte neu brauche setze ich jetzt _hzbStartLaenge neu
_hzbStartLaenge = iDiff.X
End If
End SubWenn Du Bock hast würde ich Dir per Teamviewer das ganze auch mal zeigen
Bernhard Meyer Danke
-
Hi Bernhard,
ich finde deinen Code etwas chaotisch. Setze zuerst mal Option Strict On. Den von dir geposteten Code würde ich so programmieren:Private Sub pkirm_PreviewMouseMove(sender As Object, e As MouseEventArgs) Handles pkirm.PreviewMouseMove If e.LeftButton = MouseButtonState.Pressed Then Dim parent = FindParent(sender, GetType(Border)) If parent Is Nothing Then Exit Sub Dim oldLeft = CType(parent.GetValue(Canvas.LeftProperty), Double) Dim oldWidth = parent.Width Dim actX = e.GetPosition(CType(parent, IInputElement)).X parent.Width = (actX - oldWidth / 2) * 2 parent.SetValue(Canvas.LeftProperty, oldLeft + (oldWidth - parent.Width) / 2) End If End Sub Private Function FindParent(sender As Object, type As Type) As FrameworkElement Dim element = TryCast(sender, FrameworkElement) If element Is Nothing Then Return Nothing If element.GetType Is type Then Return element Return FindParent(element.Parent, type) End Function
Um dann aber eine flüssige Arbeitsweise zu erreichen, würde ich anstelle der Mausereignisse der Ellipse für das Verschieben ein übergeordnetes Element nehmen.
Mein Ergebnis:
--
Best Regards / Viele Grüße
Peter Fleischer (former MVP for Developer Technologies)
Homepage, Tipps, Tricks
- Bearbeitet Peter Fleischer Freitag, 7. Januar 2022 19:59
-
Hallo Peter, das bekomme ich mit meinem chaotischen Code auch hin.
Die Vergößerung und verkleinerung sollte jetzt bei gedrehtem Object
entweder links oder rechts verkleinern und nicht synchron.
So wie du es auch aus der IDE kennst.
Bernhard Meyer Danke
- Bearbeitet Bernhard Meyer Freitag, 7. Januar 2022 21:24 aktualisierung
-
Hi Bernhard,
Ich habe lediglich versucht, deinen Code zu verstehen. Wie realisierst du die Drehung. Ich würde die dann auch in meinen kurzen Code einbauen.--
Best Regards / Viele Grüße
Peter Fleischer (former MVP for Developer Technologies)
Homepage, Tipps, Tricks -
Hallo Peter,
zuerst einmal VIELEN DANK für Deine Hilfe. Es hilft mir sehr !
Private _Drehung As Integer
Public Property Drehung As Integer
Get
Return _Drehung
End Get
Set(ByVal value As Integer)
_Drehung = value
boHZB.RenderTransform = New RotateTransform(value)
End Set
End Property Private Sub pkiro_PreviewMouseMove(sender As Object, e As MouseEventArgs) Handles pkiro.PreviewMouseMove
If e.LeftButton = MouseButtonState.Pressed Then
Dim iDiff As Double ' Differnezberechnung
Dim hzbGradStart As Double = Drehung 'grad
_mausMovePosition.X = e.GetPosition(Parent).X
_mausMovePosition.Y = e.GetPosition(Parent).Y
If _mausPosition.X <> _mausMovePosition.X Or _mausPosition.Y <> _mausMovePosition.Y Then
If _mausPosition.Y < _mausMovePosition.Y Then
iDiff = _mausMovePosition.Y - _mausPosition.Y
Drehung += iDiff
Else
iDiff = _mausPosition.Y - _mausMovePosition.Y
Drehung -= iDiff
End If
End If
End If
End SubBernhard Meyer Danke
-
Hallo Peter,
ich versuche deinen Vorschlag umzusetzen.
pkirm_PreviewMouseMove
Ich möchte das das Object sich ja nicht synchron verkleinert sondern wie bei einem CAD
Ziel ist es vergrössern, verkleinern, drehen
(rechts verkleinert links) (Links verkleinert rechts)
parent.SetValue(Canvas.LeftProperty, oldLeft + (oldWidth - parent.Width) / 2)
Dazu versuche ich die Zeile zu verändern. Alles was ich mache klappt nicht. Lass ich /2 weg
bleibt zwar das Object rechts stehen und es verjüngt sich links. Ich nehme jedoch den rechten PKI also
müsste links stehen bleiben und sich rechts verändern. Irgendeine IDEE ?Bernhard Meyer Danke
-
Hi Bernhard,
so richtig verstanden habe ich dein Ziel noch nicht. Hier mal eine Demo, wie ich vergrößern, verschieben und drehen würde. Am Code kann man bestimmt noch etwas verändern, wenn die genauen Ziele klar sind.XAML UserControl:
<UserControl x:Class="Window108UC1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfControlLibrary1" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" x:Name="uc"> <Canvas x:Name="cv" Background="White"> <Border x:Name="boHZB" Width="400" Height="60" RenderTransformOrigin="0.5,0.5" MaxWidth="800" MinWidth="50" BorderThickness="1,1,1,1" BorderBrush="Black" Canvas.Left="0" Canvas.Top="0"> <Border.RenderTransform> <TransformGroup> <RotateTransform Angle="{Binding Angle}"/> <TranslateTransform X="{Binding TranslateVector.X}" Y="{Binding TranslateVector.Y}"/> </TransformGroup> </Border.RenderTransform> <Grid Background="DodgerBlue" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Panel.ZIndex="0" Margin="0,0,-0,0"> <!--<Image x:Name="imgselbstklebend" Source="/imghzb/lf_sk_quer.png" Height="{Binding Height, ElementName=hzbgrid}" Width="{Binding Width, ElementName=hzbgrid}" Stretch="Fill" Margin="5,5,5,5"/>--> <Label x:Name="lblBeschriftung" MinWidth="160" Content="Bernhard" HorizontalContentAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Top" Panel.ZIndex="2" /> <Label x:Name="lblLaenge" MinWidth="160" Content="{Binding Width, ElementName=boHZB}" HorizontalContentAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Bottom" Panel.ZIndex="2" /> <Ellipse x:Name="pkilo" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="-4,-4,0,0" Panel.ZIndex="2" Cursor="SizeNESW" Visibility="Visible"/> <Ellipse x:Name="pkimo" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="center" VerticalAlignment="Top" Margin="-4,-4,0,0" Panel.ZIndex="2" Cursor="ScrollN" Visibility="Visible" ToolTip="rechte maustaste kopiert die Heizbahn"/> <Ellipse x:Name="pkiro" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,-4,-4,0" Panel.ZIndex="2" Cursor="SizeNWSE" Visibility="Visible"/> <Ellipse x:Name="pkirm" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,-4,-4,0" Panel.ZIndex="21" Cursor="SizeWE" Visibility="Visible"/> <Ellipse x:Name="pkimi" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="center" VerticalAlignment="center" Margin="0,0,0,0" Panel.ZIndex="2" Cursor="ScrollAll" Visibility="Visible"/> <Ellipse x:Name="pkilm" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="-4,-4,0,0" Panel.ZIndex="2" Cursor="SizeWE" Visibility="Visible"/> <Ellipse x:Name="pkilu" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="-4,0,0,-4" Panel.ZIndex="2" Cursor="SizeNWSE" Visibility="Visible"/> <Ellipse x:Name="pkium" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="center" VerticalAlignment="Bottom" Margin="-4,0,0,-4" Panel.ZIndex="2" Cursor="ScrollS" Visibility="Visible"/> <Ellipse x:Name="pkiru" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,-4,-4" Panel.ZIndex="2" Cursor="SizeNESW" Visibility="Visible"/> </Grid> </Border> </Canvas> </UserControl>
Und der CodeBehind des UserControls:
Imports System.ComponentModel Imports System.Runtime.CompilerServices Public Class Window108UC1 Implements INotifyPropertyChanged Public Sub New() ' This call is required by the designer. InitializeComponent() ' Add any initialization after the InitializeComponent() call. Me.DataContext = Me End Sub Private MoveType As MoveTypeEnum Private Container As FrameworkElement Private MoveObject As FrameworkElement Private StartPositionInContainer As Point Private CenterPositionInContainer As Point Private TranslateVectorOld As Vector Public Property TranslateVector As Vector Private AngleOld As Double Public Property Angle As Double Private Sub pkirm_PreviewMouseDown(sender As Object, e As MouseButtonEventArgs) Handles pkirm.PreviewMouseDown MoveType = MoveTypeEnum.WidthLeft CacheValues(sender, e) End Sub Private Sub pkium_PreviewMouseDown(sender As Object, e As MouseButtonEventArgs) Handles pkium.PreviewMouseDown MoveType = MoveTypeEnum.HeigthBottom CacheValues(sender, e) End Sub Private Sub pkimi_PreviewMouseDown(sender As Object, e As MouseButtonEventArgs) Handles pkimi.PreviewMouseDown MoveType = MoveTypeEnum.Center CacheValues(sender, e) End Sub Private Sub pkiru_PreviewMouseDown(sender As Object, e As MouseButtonEventArgs) Handles pkiru.PreviewMouseDown MoveType = MoveTypeEnum.RotateBottomRight CacheValues(sender, e) End Sub Private Sub CacheValues(sender As Object, e As MouseButtonEventArgs) Container = cv MoveObject = boHZB StartPositionInContainer = e.GetPosition(Container) AngleOld = Angle TranslateVectorOld = TranslateVector CenterPositionInContainer = New Point(StartPositionInContainer.X - MoveObject.Width / 2, StartPositionInContainer.Y - MoveObject.Height / 2) End Sub Private Sub uc_PreviewMouseMove(sender As Object, e As MouseEventArgs) Handles uc.PreviewMouseMove If MoveObject Is Nothing OrElse e.LeftButton <> MouseButtonState.Pressed Then MoveType = MoveTypeEnum.None Exit Sub End If Select Case MoveType Case MoveTypeEnum.WidthLeft MoveObject.Width = e.GetPosition(MoveObject).X Case MoveTypeEnum.HeigthBottom MoveObject.Height = e.GetPosition(MoveObject).Y Case MoveTypeEnum.Center Dim v = TranslateVector v.X = e.GetPosition(Container).X - StartPositionInContainer.X v.Y = e.GetPosition(Container).Y - StartPositionInContainer.Y TranslateVector = v OnPropChanged(NameOf(TranslateVector)) Case MoveTypeEnum.RotateBottomRight Dim v1 = New Vector(StartPositionInContainer.X - CenterPositionInContainer.X, StartPositionInContainer.Y - CenterPositionInContainer.Y) Dim v2 = New Vector(e.GetPosition(Container).X - CenterPositionInContainer.X, e.GetPosition(Container).Y - CenterPositionInContainer.Y) Angle = Vector.AngleBetween(v1, v2) OnPropChanged(NameOf(Angle)) End Select e.Handled = True End Sub Private Sub uc_PreviewMouseUp(sender As Object, e As MouseButtonEventArgs) Handles uc.PreviewMouseUp MoveType = MoveTypeEnum.None End Sub Enum MoveTypeEnum None WidthLeft HeigthBottom Center RotateBottomRight End Enum Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged Private Sub OnPropChanged(<CallerMemberName> Optional propName As String = "") RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propName)) End Sub End Class
Das Ergebnis sieht dann so aus:
--
Best Regards / Viele Grüße
Peter Fleischer (former MVP for Developer Technologies)
Homepage, Tipps, Tricks -
Hallo Peter
genau so solle sein, jedoch hast Du das gleiche Problem:
Wenn du im gedrehten Zustand die Länge änderst verschiebt sich das Object
Es soll aber auf der gegenüberliegende Seite stehen bleiben.
Dein Code oben ist absolut COOL.
Nach dem Motto gedreht, verkleinern, jedoch gegenüber an der Stelle bleiben !
und zwar auf die Mitte bezogen - also ich schiebe pkilm nach links oder rechts dann soll pkirm am Punkt bleiben.
Danke Dir
Bernhard Meyer Danke
-
Hi Bernhard,
da du nur abschnittsweise deine Vorstellungen preisgibst, ist es natürlich schwer, eine passende Lösung zu finden. In deiner Anwort vom Freitag, 7. Januar 2022 21:22 hattest du aber eine andere Forderung. Hier mal einen CodeBehind, so wie ich deine neuen Ziele verstanden habe:Imports System.ComponentModel Imports System.Runtime.CompilerServices Public Class Window108UC1 Implements INotifyPropertyChanged Public Sub New() ' This call is required by the designer. InitializeComponent() ' Add any initialization after the InitializeComponent() call. Me.DataContext = Me End Sub Private MoveType As MoveTypeEnum Private Container As FrameworkElement Private MoveObject As FrameworkElement Private StartPositionInContainer As Point Private CenterPositionInContainer As Point Private MoveObjectSizeOld As Size Private TranslateVectorOld As Vector Public Property TranslateVector As Vector Private AngleOld As Double Public Property Angle As Double Private Sub pkirm_PreviewMouseDown(sender As Object, e As MouseButtonEventArgs) Handles pkirm.PreviewMouseDown MoveType = MoveTypeEnum.WidthLeft CacheValues(sender, e) End Sub Private Sub pkium_PreviewMouseDown(sender As Object, e As MouseButtonEventArgs) Handles pkium.PreviewMouseDown MoveType = MoveTypeEnum.HeigthBottom CacheValues(sender, e) End Sub Private Sub pkimi_PreviewMouseDown(sender As Object, e As MouseButtonEventArgs) Handles pkimi.PreviewMouseDown MoveType = MoveTypeEnum.Center CacheValues(sender, e) End Sub Private Sub pkiru_PreviewMouseDown(sender As Object, e As MouseButtonEventArgs) Handles pkiru.PreviewMouseDown MoveType = MoveTypeEnum.RotateBottomRight CacheValues(sender, e) End Sub Private Sub CacheValues(sender As Object, e As MouseButtonEventArgs) Container = cv MoveObject = boHZB MoveObjectSizeOld = New Size(MoveObject.ActualWidth, MoveObject.ActualHeight) StartPositionInContainer = e.GetPosition(Container) AngleOld = Angle TranslateVectorOld = TranslateVector CenterPositionInContainer = New Point(StartPositionInContainer.X - MoveObject.Width / 2, StartPositionInContainer.Y - MoveObject.Height / 2) End Sub Private Sub uc_PreviewMouseMove(sender As Object, e As MouseEventArgs) Handles uc.PreviewMouseMove If MoveObject Is Nothing OrElse e.LeftButton <> MouseButtonState.Pressed Then MoveType = MoveTypeEnum.None Exit Sub End If Dim diffVector = New Vector(e.GetPosition(Container).X - StartPositionInContainer.X, e.GetPosition(Container).Y - StartPositionInContainer.Y) Select Case MoveType Case MoveTypeEnum.WidthLeft MoveObject.Width = MoveObjectSizeOld.Width + diffVector.X Dim v = TranslateVector v.X = TranslateVectorOld.X - diffVector.X / 2 TranslateVector = v OnPropChanged(NameOf(TranslateVector)) Case MoveTypeEnum.HeigthBottom MoveObject.Height = MoveObjectSizeOld.Height + diffVector.Y Dim v = TranslateVector v.Y = TranslateVectorOld.Y - diffVector.Y / 2 TranslateVector = v OnPropChanged(NameOf(TranslateVector)) Case MoveTypeEnum.Center Dim v = TranslateVector v.X = e.GetPosition(Container).X - StartPositionInContainer.X v.Y = e.GetPosition(Container).Y - StartPositionInContainer.Y TranslateVector = v OnPropChanged(NameOf(TranslateVector)) Case MoveTypeEnum.RotateBottomRight Dim v1 = New Vector(StartPositionInContainer.X - CenterPositionInContainer.X, StartPositionInContainer.Y - CenterPositionInContainer.Y) Dim v2 = New Vector(e.GetPosition(Container).X - CenterPositionInContainer.X, e.GetPosition(Container).Y - CenterPositionInContainer.Y) Angle = Vector.AngleBetween(v1, v2) OnPropChanged(NameOf(Angle)) End Select e.Handled = True End Sub Private Sub uc_PreviewMouseUp(sender As Object, e As MouseButtonEventArgs) Handles uc.PreviewMouseUp MoveType = MoveTypeEnum.None End Sub Enum MoveTypeEnum None WidthLeft HeigthBottom Center RotateBottomRight End Enum Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged Private Sub OnPropChanged(<CallerMemberName> Optional propName As String = "") RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propName)) End Sub End Class
Das Ergebnis sieht so aus:
--
Best Regards / Viele Grüße
Peter Fleischer (former MVP for Developer Technologies)
Homepage, Tipps, Tricks- Bearbeitet Peter Fleischer Montag, 10. Januar 2022 17:44
-
Hallo Peter,
zuerst einmal vielen Dank für Deine Bereitschaft mir zu helfen.
Du meintest mein Vorstellung wäre nicht ganz klar. Dein Ergebnis, habe ich auch schon.
Plazier in der IDE mal ein Rectangle. Das kannst du dort vergrößern und verkleinern und drehen. Jedoch passiert im gedrehten Zustand folgendes. Die gegenüberliegen Seite bleibt am Ausgangspunkt.
Bei deinem Beispiel werden beide Seiten verkleinert. Diese Ergebnis, ist kein Problem.
Versuch mal im gedrehten Zustand nur die Seite zu verkleinern, bei der auch der Mauszeiger ist. Dann rutscht das ganze durch die Gegend und genau dass möchte ich verhindern. Ich würde die gerne ein Beispiee zeigen, aber ich weiß nicht wie ich so eine kleine Animation erstelle :-(
Ich bae jetzt in mühseliger Kleinarbeit in 5er Angle Schritten die PosAlt Werte nach der Verkleinerung ermittelt, damit ich wieder in die PosAlt per Left und Top nach dem verkleinern springen springen kann.
VIELEN VIELEN DANKE
Bernhard Meyer Danke
-
Hi Bernhard,
hier mal eine andere Version von mir:<UserControl x:Class="Window108UC1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfControlLibrary1" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" x:Name="uc"> <Canvas x:Name="cv" Background="White"> <Border x:Name="boHZB" Width="400" Height="60" RenderTransformOrigin="0.5,0.5" MaxWidth="800" MinWidth="50" BorderThickness="1,1,1,1" BorderBrush="Black" Canvas.Left="0" Canvas.Top="0"> <Border.RenderTransform> <TransformGroup> <RotateTransform Angle="{Binding Angle}" CenterX="{Binding RotatePositionInMoveObject.X}" CenterY="{Binding RotatePositionInMoveObject.Y}"/> <TranslateTransform X="{Binding TranslateVector.X}" Y="{Binding TranslateVector.Y}"/> </TransformGroup> </Border.RenderTransform> <Grid Background="DodgerBlue" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Panel.ZIndex="0" Margin="0,0,-0,0"> <!--<Image x:Name="imgselbstklebend" Source="/imghzb/lf_sk_quer.png" Height="{Binding Height, ElementName=hzbgrid}" Width="{Binding Width, ElementName=hzbgrid}" Stretch="Fill" Margin="5,5,5,5"/>--> <Label x:Name="lblBeschriftung" MinWidth="160" Content="Bernhard" HorizontalContentAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Top" Panel.ZIndex="2" /> <Label x:Name="lblLaenge" MinWidth="160" Content="{Binding Width, ElementName=boHZB}" HorizontalContentAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Bottom" Panel.ZIndex="2" /> <Ellipse x:Name="pkilo" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="-4,-4,0,0" Panel.ZIndex="2" Cursor="SizeNESW" Visibility="Visible"/> <Ellipse x:Name="pkimo" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="center" VerticalAlignment="Top" Margin="-4,-4,0,0" Panel.ZIndex="2" Cursor="ScrollN" Visibility="Visible" ToolTip="rechte maustaste kopiert die Heizbahn"/> <Ellipse x:Name="pkiro" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,-4,-4,0" Panel.ZIndex="2" Cursor="SizeNWSE" Visibility="Visible"/> <Ellipse x:Name="pkirm" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,-4,-4,0" Panel.ZIndex="21" Cursor="SizeWE" Visibility="Visible"/> <Ellipse x:Name="pkimi" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="center" VerticalAlignment="center" Margin="0,0,0,0" Panel.ZIndex="2" Cursor="ScrollAll" Visibility="Visible"/> <Ellipse x:Name="pkilm" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="-4,-4,0,0" Panel.ZIndex="2" Cursor="SizeWE" Visibility="Visible"/> <Ellipse x:Name="pkilu" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="-4,0,0,-4" Panel.ZIndex="2" Cursor="SizeNWSE" Visibility="Visible"/> <Ellipse x:Name="pkium" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="center" VerticalAlignment="Bottom" Margin="-4,0,0,-4" Panel.ZIndex="2" Cursor="ScrollS" Visibility="Visible"/> <Ellipse x:Name="pkiru" Width="8" Height="8" Fill="Black" StrokeThickness="1" Stroke="Red" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,-4,-4" Panel.ZIndex="2" Cursor="SizeNESW" Visibility="Visible"/> </Grid> </Border> </Canvas> </UserControl>
Dazu der CodeBehind:
Imports System.ComponentModel Imports System.Runtime.CompilerServices Public Class Window108UC1 Implements INotifyPropertyChanged Public Sub New() ' This call is required by the designer. InitializeComponent() ' Add any initialization after the InitializeComponent() call. Me.DataContext = Me End Sub Private MoveType As MoveTypeEnum Private Container As FrameworkElement Private MoveObject As FrameworkElement Private StartPositionInContainer As Vector Public Property RotatePositionInMoveObject As Point Private MoveObjectSizeOld As Size Private TranslateVectorOld As Vector Public Property TranslateVector As Vector Private AngleOld As Double Public Property Angle As Double Private Sub pkirm_PreviewMouseDown(sender As Object, e As MouseButtonEventArgs) Handles pkirm.PreviewMouseDown MoveType = MoveTypeEnum.WidthLeft CacheValues(sender, e) End Sub Private Sub pkium_PreviewMouseDown(sender As Object, e As MouseButtonEventArgs) Handles pkium.PreviewMouseDown MoveType = MoveTypeEnum.HeigthBottom CacheValues(sender, e) End Sub Private Sub pkimi_PreviewMouseDown(sender As Object, e As MouseButtonEventArgs) Handles pkimi.PreviewMouseDown MoveType = MoveTypeEnum.Center CacheValues(sender, e) End Sub Private Sub pkiru_PreviewMouseDown(sender As Object, e As MouseButtonEventArgs) Handles pkiru.PreviewMouseDown MoveType = MoveTypeEnum.RotateBottomRight CacheValues(sender, e) End Sub Private Sub CacheValues(sender As Object, e As MouseButtonEventArgs) Container = cv MoveObject = boHZB AngleOld = Angle TranslateVectorOld = TranslateVector MoveObjectSizeOld = New Size(MoveObject.ActualWidth, MoveObject.ActualHeight) StartPositionInContainer = e.GetPosition(Container).ToVector RotatePositionInMoveObject = New Point(-MoveObject.Width / 2, -MoveObject.Height / 2) End Sub Private Sub uc_PreviewMouseMove(sender As Object, e As MouseEventArgs) Handles uc.PreviewMouseMove If MoveObject Is Nothing OrElse e.LeftButton <> MouseButtonState.Pressed Then MoveType = MoveTypeEnum.None Exit Sub End If Dim diffVector = New Vector(e.GetPosition(Container).X - StartPositionInContainer.X, e.GetPosition(Container).Y - StartPositionInContainer.Y) Select Case MoveType Case MoveTypeEnum.WidthLeft MoveObject.Width = MoveObjectSizeOld.Width + diffVector.X RotatePositionInMoveObject = New Point(-MoveObject.Width / 2, -MoveObject.Height / 2) OnPropChanged(NameOf(RotatePositionInMoveObject)) Case MoveTypeEnum.HeigthBottom MoveObject.Height = MoveObjectSizeOld.Height + diffVector.Y RotatePositionInMoveObject = New Point(-MoveObject.Width / 2, -MoveObject.Height / 2) OnPropChanged(NameOf(RotatePositionInMoveObject)) Case MoveTypeEnum.Center TranslateVector = Vector.Subtract(Vector.Add(TranslateVectorOld, e.GetPosition(Container).ToVector), StartPositionInContainer) OnPropChanged(NameOf(TranslateVector)) Case MoveTypeEnum.RotateBottomRight Dim v1 = Vector.Subtract(StartPositionInContainer, TranslateVectorOld) Dim v2 = Vector.Subtract(New Vector(e.GetPosition(Container).X, e.GetPosition(Container).Y), TranslateVectorOld) Angle = AngleOld + Vector.AngleBetween(v1, v2) OnPropChanged(NameOf(Angle)) RotatePositionInMoveObject = New Point(-MoveObject.Width / 2, -MoveObject.Height / 2) OnPropChanged(NameOf(RotatePositionInMoveObject)) End Select e.Handled = True End Sub Private Sub uc_PreviewMouseUp(sender As Object, e As MouseButtonEventArgs) Handles uc.PreviewMouseUp MoveType = MoveTypeEnum.None End Sub Enum MoveTypeEnum None WidthLeft HeigthBottom Center RotateBottomRight End Enum Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged Private Sub OnPropChanged(<CallerMemberName> Optional propName As String = "") RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propName)) End Sub End Class Public Module Extensions <Extension()> Public Function ToVector(ByVal p As Point) As Vector Return New Vector(p.X, p.Y) End Function End Module
Und das sieht dann so aus:
--
Best Regards / Viele Grüße
Peter Fleischer (former MVP for Developer Technologies)
Homepage, Tipps, Tricks- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Moderator Montag, 17. Januar 2022 13:29
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Moderator Freitag, 28. Januar 2022 11:21
-
Hi Bernhard,
da ein Vector praktisch ein Endpunkt ist, kannst du natürlich auch alles nur mit Punkten machen. Du musst dann aber die Vektorrechnung wie Add, Subtract, AngleBetween selbst implementieren. Und wenn du das nicht kapselst (z.B. in Extensions), dann bekommst du schnell einen fast unüberschaubaren Code.--
Best Regards / Viele Grüße
Peter Fleischer (former MVP for Developer Technologies)
Homepage, Tipps, Tricks