Страницы

Поиск по вопросам

среда, 29 января 2020 г.

Нарисовать Button при клике на окно WPF

#c_sharp #wpf


Я хочу сделать приложение : юзер кликает и зажимает мышку, а когда он её отпускает,
рисуется 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);
}


Это не работает, кнопки рисуются слишком большими или вообще не рисуются. Что я делаю
не так и как сделать так, чтобы это заработало? 
    


Ответы

Ответ 1



Координаты надо считать для того контрола, куда вкладываете кнопку. К данном случае для грида. Маргин справа и снизу - это не координаты, это расстояние от края контрола до края кнопки (в вашем случае) Немного переписал ваш код 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); }

Ответ 2



Для того, чтобы располагать контролы по абсолютным координатам, правильно использовать Canvas, он для этого специально предназначен. Поэтому я бы написал так: XAML: 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 выгрузит его до отпускания мыши.

Ответ 3



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); }

Комментариев нет:

Отправить комментарий