Я хочу сделать приложение : юзер кликает и зажимает мышку, а когда он её отпускает, рисуется Button
у которого левый верхний угол это координаты клика (событие MouseDown
), а правый нижний - координаты места где пользователь отпустил кнопку мыши (событие MouseUp
). Вот код для MouseDown
:
private void MainWindow_MouseDown(object sender, MouseButtonEventArgs e)
{
StartPoint = e.GetPosition(this);
//Свойство StartPoint объявляется сверху таким образом
//private System.Windows.Point StartPoint { get; set; }
}
Вот код для MouseUp
:
private void MainWindow_MouseUp(object sender, MouseButtonEventArgs e)
{
EndPoint = e.GetPosition(this);
//Свойство EndPoint объявляется сверху таким образом
//private System.Windows.Point EndPoint { get; set; }
Button temp = new Button();
temp.Margin = new Thickness(StartPoint.X, StartPoint.Y, EndPoint.X, EndPoint.Y);
temp.Background = new SolidColorBrush(Colors.Blue);
temp.Content = "Do not click me!";
mainGrid.Children.Add(temp);
}
Это не работает, кнопки рисуются слишком большими или вообще не рисуются. Что я делаю не так и как сделать так, чтобы это заработало?
Немного переписал ваш код
private void MainWindow_MouseDown(object sender, MouseButtonEventArgs e)
{
StartPoint = e.GetPosition(mainGrid);
//Свойство StartPoint объявляется сверху таким образом
//private System.Windows.Point StartPoint { get; set; }
}
private void MainWindow_MouseUp(object sender, MouseButtonEventArgs e)
{
EndPoint = e.GetPosition(mainGrid);
//Свойство EndPoint объявляется сверху таким образом
//private System.Windows.Point EndPoint { get; set; }
Button temp = new Button();
temp.Margin = new Thickness(StartPoint.X, StartPoint.Y, mainGrid.ActualWidth - EndPoint.X, mainGrid.ActualHeight - EndPoint.Y);
temp.Background = new SolidColorBrush(Colors.Blue);
temp.Content = "Do not click me!";
mainGrid.Children.Add(temp);
}
Для того, чтобы располагать контролы по абсолютным координатам, правильно использовать Canvas
, он для этого специально предназначен. Поэтому я бы написал так:
XAML:
<Grid>
<Canvas MouseLeftButtonDown="OnCanvasLeftMouseDown" Background="Transparent"/>
</Grid>
Code-behind:
void OnCanvasLeftMouseDown(object sender, MouseButtonEventArgs eDown)
{
var canvas = (Canvas)sender;
var startPos = eDown.GetPosition(canvas);
canvas.MouseLeftButtonUp += OnUp;
void OnUp(object _, MouseButtonEventArgs eUp) // захватим позицию начала
{
canvas.MouseLeftButtonUp -= OnUp;
var endPos = eUp.GetPosition(canvas);
var button = new Button()
{
Content = "Do not click me!",
Width = Math.Abs(endPos.X - startPos.X),
Height = Math.Abs(endPos.Y - startPos.Y)
};
Canvas.SetLeft(button, Math.Min(startPos.X, endPos.X));
Canvas.SetTop(button, Math.Min(startPos.Y, endPos.Y));
canvas.Children.Add(button);
}
}
С подачи @tym32167, более строгий вариант:
void OnCanvasLeftMouseDown(object sender, MouseButtonEventArgs eDown)
{
var canvas = (Canvas)sender;
var startPos = eDown.GetPosition(canvas);
canvas.MouseLeftButtonUp += OnUp;
canvas.Unloaded += Unsubscribe;
Mouse.Capture(canvas);
void OnUp(object _, MouseButtonEventArgs eUp) // захватим позицию начала
{
Mouse.Capture(null);
Unsubscribe(_, eUp);
var endPos = eUp.GetPosition(canvas);
if (!canvas.IsMouseOver)
return;
var button = new Button()
{
Content = "Do not click me!",
Width = Math.Abs(endPos.X - startPos.X),
Height = Math.Abs(endPos.Y - startPos.Y)
};
Canvas.SetLeft(button, Math.Min(startPos.X, endPos.X));
Canvas.SetTop(button, Math.Min(startPos.Y, endPos.Y));
canvas.Children.Add(button);
}
void Unsubscribe(object _, RoutedEventArgs e)
{
canvas.MouseLeftButtonUp -= OnUp;
canvas.Unloaded -= Unsubscribe;
}
}
Добавлен захват мыши, чтобы отпускание её происходило в том же контексте. Также добавлена подписка на выгрузку Canvas
'а, на случай, если логика UI выгрузит его до отпускания мыши.
private void Grid_PreviewMouseDown(object sender, MouseButtonEventArgs e) {
Mouse.Capture(sender as IInputElement);
}
private void Grid_PreviewMouseUp(object sender, MouseButtonEventArgs e) {
Point upPoint = e.GetPosition(sender as Grid);
if (upPoint.X < 0 || upPoint.X > mainGrid.ActualWidth ||
upPoint.Y < 0 || upPoint.Y > mainGrid.ActualHeight)
return;
Mouse.Capture(null);
Button button = new Button();
button.Margin = new Thickness(upPoint.X, upPoint.Y, 0, 0);
button.VerticalAlignment = VerticalAlignment.Top;
button.HorizontalAlignment = HorizontalAlignment.Left;
button.Background = new SolidColorBrush(Colors.Blue);
button.Content = "Do not click me!";
button.Width = 120;
button.Height = 20;
mainGrid.Children.Add(button);
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Столкнулся с такой проблемой, что не получается нормально прибайндить комбобокс к базе данныхИмеется код:
Проект, написанный на языке C#Среда: Visual Studio 2012