Moja aplikacja WPF ma UserControl
, która ma wyglądać i zachowywać się jak okno wyskakujące, ale nie jest to okno. Powód, dla którego kontrola nie pochodzi z klasy Window
, ponieważ zawiera wirtualną klawiaturę ekranową innej firmy i ta kontrolka musi być w tym samym oknie, co kontrolki, do których wysyła znaki wejściowe, kiedy klikniesz jego przyciski. Jeśli sterowanie klawiaturą nie znajduje się w tym samym oknie, nie widać nawet kontrolek TextBox
.Jak ustawić sterowanie przez użytkownika na ekranie jak okno
Problem, który mam, to wydajność jest nędzna podczas przeciągania okna dialogowego. Jest wystarczająco powolny, gdy mysz opuszcza obszar przeciągania i przestaje podążać za myszą. Potrzebuję lepszego sposobu.
Oto fragment z XAML do sterowania:
<Grid Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border Background="{DynamicResource PopupBackground}"
BorderBrush="{DynamicResource PopupBorder}"
BorderThickness="5,5,5,0"
MouseLeftButtonDown="Grid_MouseLeftButtonDown"
MouseLeftButtonUp="Grid_MouseLeftButtonUp"
MouseMove="Grid_MouseMove">
. . .
</Border>
</Grid>
oto obsługi zdarzeń myszy:
private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
Canvas canvas = Parent as Canvas;
if (canvas == null) {
throw new InvalidCastException("The parent of a KeyboardPopup control must be a Canvas.");
}
DraggingControl = true;
CurrentMousePosition = e.GetPosition(canvas);
e.Handled = true;
}
private void Grid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) {
Canvas canvas = Parent as Canvas;
if (canvas == null) {
throw new InvalidCastException("The parent of a KeyboardPopup control must be a Canvas.");
}
if (DraggingControl) {
Point mousePosition = e.GetPosition(canvas);
// Correct the mouse coordinates in case they go off the edges of the control
if (mousePosition.X < 0.0) mousePosition.X = 0.0; else if (mousePosition.X > canvas.ActualWidth) mousePosition.X = canvas.ActualWidth;
if (mousePosition.Y < 0.0) mousePosition.Y = 0.0; else if (mousePosition.Y > canvas.ActualHeight) mousePosition.Y = canvas.ActualHeight;
// Compute the new Left & Top coordinates of the control
Canvas.SetLeft(this, Left += mousePosition.X - CurrentMousePosition.X);
Canvas.SetTop(this, Top += mousePosition.Y - CurrentMousePosition.Y);
}
e.Handled = true;
}
private void Grid_MouseMove(object sender, MouseEventArgs e) {
Canvas canvas = Parent as Canvas;
if (canvas == null) {
// It is not. Throw an exception
throw new InvalidCastException("The parent of a KeyboardPopup control must be a Canvas.");
}
if (DraggingControl && e.LeftButton == MouseButtonState.Pressed) {
Point mousePosition = e.GetPosition(canvas);
// Correct the mouse coordinates in case they go off the edges of the control
if (mousePosition.X < 0.0) mousePosition.X = 0.0; else if (mousePosition.X > canvas.ActualWidth ) mousePosition.X = canvas.ActualWidth;
if (mousePosition.Y < 0.0) mousePosition.Y = 0.0; else if (mousePosition.Y > canvas.ActualHeight) mousePosition.Y = canvas.ActualHeight;
// Compute the new Left & Top coordinates of the control
Canvas.SetLeft(this, Left += mousePosition.X - CurrentMousePosition.X);
Canvas.SetTop (this, Top += mousePosition.Y - CurrentMousePosition.Y);
CurrentMousePosition = mousePosition;
}
e.Handled = true;
}
Należy zauważyć, że kontrola musi być umieszczony wewnątrz Canvas
w oknie, które się go używa .
Nie mogę użyć DragMove
, ponieważ jest to metoda klasy Window
i ta klasa wywodzi się z UserControl
. Jak poprawić wydajność przeciągania tej kontrolki? Czy muszę uciekać się do API Win32?
http://stackoverflow.com/a/38830033/2507782 –