Making a simple graph using a slider - c#

I want to use a slider to create a simple graph containing both the value for Celsius and Fahrenheit and update as I move the slider. Now the graph for Fahrenheit is showing and updates as I move the slider but the graph for Celsius does not show. The slider has a minimum="0" and maximum="100" in XAML. Targetting WPF.
What am I doing wrong?
Edit: added XAML code + target
Edit2: placed updated code underneath original code
<Window x:Class="O6._4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:O6._4"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Button Content="Calculate" HorizontalAlignment="Left" Margin="30,75,0,0" VerticalAlignment="Top" Width="75" Name="CalculateButton" Click="CalculateButton_Click" HorizontalContentAlignment="Center"/>
<Button Content="Clear" HorizontalAlignment="Left" Margin="30,105,0,0" VerticalAlignment="Top" Width="75" Name="ClearButton" Click="ClearButton_Click" HorizontalContentAlignment="Center"/>
<Label Content="xxx" HorizontalAlignment="Left" Margin="130,32,0,0" VerticalAlignment="Top" Name="fahrenheitLabel"/>
<TextBlock HorizontalAlignment="Left" Margin="130,10,0,0" TextWrapping="Wrap" Text="° Fahrenheit" VerticalAlignment="Top"/>
<Slider HorizontalAlignment="Left" Margin="30,145,0,0" VerticalAlignment="Top" Width="127" Name="celsiusSlider" ValueChanged="celsiusSlider_ValueChanged" Minimum="0" Maximum="100"/>
<Label Content="xxx" HorizontalAlignment="Left" Margin="30,168,0,0" VerticalAlignment="Top" Name="celsiusLabel"/>
<Canvas HorizontalAlignment="Left" Height="250" Margin="220,40,0,0" VerticalAlignment="Top" Width="250" Name="paperCanvas" Background="LightGray"/>
<TextBlock HorizontalAlignment="Left" Margin="250,10,0,0" TextWrapping="Wrap" Text="°C" VerticalAlignment="Top"/>
<TextBlock HorizontalAlignment="Left" Margin="315,10,0,0" TextWrapping="Wrap" Text="°F" VerticalAlignment="Top"/>
</Grid>
{
public partial class MainWindow : Window
{
private int celsius;
private int fahrenheit;
private SolidColorBrush brush;
private Rectangle rectangle;
public MainWindow()
{
InitializeComponent();
celsiusLabel.Content = Convert.ToString(celsiusSlider.Value);
fahrenheitLabel.Content = Convert.ToString(32);
brush = new SolidColorBrush(Colors.Blue);
CreateRectangle(paperCanvas, brush, celsius, 20);
CreateRectangle(paperCanvas, brush, fahrenheit, 80);
}
private void CalculateButton_Click(object sender, RoutedEventArgs e)
{
}
private void ClearButton_Click(object sender, RoutedEventArgs e)
{
}
private void celsiusSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
celsius = Convert.ToInt32(celsiusSlider.Value);
celsiusLabel.Content = Convert.ToString(celsius);
fahrenheit = celsius * 9 / 5 + 32;
fahrenheitLabel.Content = Convert.ToString(fahrenheit);
//UpdateRectangle(celsiusSlider.Value);
UpdateRectangle(celsius);
UpdateRectangle(fahrenheit);
}
private void CreateRectangle(Canvas drawingArea, SolidColorBrush brush, int temperatureValue, int xPosition)
{
rectangle = new Rectangle
{
Width = 40,
Height = temperatureValue,
Margin = new Thickness(xPosition,0,0,0),
Stroke = brush,
Fill = brush,
};
drawingArea.Children.Add(rectangle);
}
private void UpdateRectangle(double sliderValue)
{
rectangle.Height = sliderValue;
}
}
Updated code
public partial class MainWindow : Window
{
private int celsius;
private int fahrenheit;
private SolidColorBrush brush;
private Rectangle celsiusRectangle;
private Rectangle fahrenheitRectangle;
public MainWindow()
{
InitializeComponent();
celsiusLabel.Content = Convert.ToString(celsiusSlider.Value);
fahrenheitLabel.Content = Convert.ToString(32);
brush = new SolidColorBrush(Colors.Blue);
celsiusRectangle = CreateRectangle(paperCanvas, brush, celsius, 20);
fahrenheitRectangle = CreateRectangle(paperCanvas, brush, fahrenheit, 80);
}
private void CalculateButton_Click(object sender, RoutedEventArgs e)
{
}
private void ClearButton_Click(object sender, RoutedEventArgs e)
{
}
private void celsiusSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
celsius = Convert.ToInt32(celsiusSlider.Value);
celsiusLabel.Content = Convert.ToString(celsius);
fahrenheit = celsius * 9 / 5 + 32;
fahrenheitLabel.Content = Convert.ToString(fahrenheit);
UpdateRectangle();
}
private Rectangle CreateRectangle(Canvas drawingArea, SolidColorBrush brush, int temperatureValue, int xPosition)
{
var rectangle = new Rectangle
{
Width = 40,
Height = temperatureValue,
Margin = new Thickness(xPosition,0,0,0),
Stroke = brush,
Fill = brush,
};
drawingArea.Children.Add(rectangle);
return rectangle;
}
private void UpdateRectangle()
{
celsiusRectangle.Height = celsius;
fahrenheitRectangle.Height = fahrenheit;
}
}
}

CreateRectangle function has issue. Because you only have one private Rectangle rectangle variable. Last call CreateRectangle override celsus rectangle and lost handler. Then only fahrenheit rectangle work.
Use 2 Rectangle variable and change CreateRectangle function
private Rectangle CreateRectangle(Canvas drawingArea, SolidColorBrush brush, int temperatureValue, int xPosition)
{
var rectangle = new Rectangle //<-- Made change here
{
Width = 40,
Height = temperatureValue,
Margin = new Thickness(xPosition,0,0,0),
Stroke = brush,
Fill = brush,
};
drawingArea.Children.Add(rectangle);
return rectangle; //<-- Made change here
}
then create using like this
celsuiusRectangle= CreateRectangle(paperCanvas, brush, celsius, 20);
fahrenheitRectangle= CreateRectangle(paperCanvas, brush, fahrenheit, 80);

Related

How to draw a rectangle from user input using WPF

I want the user to enter the width and height of the rectangle and I want the rectangle to appear immediately after numbers have been entered. I don't want to have to push any buttons to have the rectangle appear.
I had the rectangle code working when I entered numbers for the height and width but when I changed it to variables from the user input textbox, nothing appears on the screen.
Here's my XAML:
TextBox Text="{Binding xcoord, Mode=OneWay}" Name="x" Grid.Row="1" Height="20" Width="40" Grid.Column="2"></TextBox>
TextBox Text="{Binding ycoord, Mode=OneWay}" Name="y" Grid.Row="2" Height="20" Width="40" Grid.Column="2"></TextBox
Here's my C#:
public FEModel()
{
InitializeComponent();
CreateARectangle();
}
private double xval;
public double xcoord
{
get { return xval; }
}
private double yval;
public double ycoord
{
get { return yval; }
}
public void CreateARectangle()
{
// Creates a Rectangle
Rectangle rect = new Rectangle();
rect.Height = ycoord;
rect.Width = xcoord;
// Create a Brush
SolidColorBrush colorbrush= new SolidColorBrush();
colorbrush.Color = Colors.Red;
colorbrush.Opacity = .3;
SolidColorBrush blackBrush = new SolidColorBrush();
blackBrush.Color = Colors.Black;
// Set Rectangle's width and color
rect.StrokeThickness = 1;
rect.Stroke = blackBrush;
// Fill rectangle with color
rect.Fill =colorbrush;
// Add Rectangle to the Grid.
can.Children.Add(rect);
}
I expect the rectangle to appear on the canvas as soon as the user enters x and y coordinates but instead, nothing happens.
You need to use two way binding for your text boxes.
Here is a fully working sample.
Window Xaml: Note that the default update trigger for textbox is 'LostFocus'. In my example i set to 'PropertyChanged' so the rectangle updates as soon as the user changes a value.
<Window x:Class="WpfApp9.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp9"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid Name="can">
<TextBox Text="{Binding xcoord, UpdateSourceTrigger=PropertyChanged}" Name="x" Height="20" Width="40" Margin="40,51,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<TextBox Text="{Binding ycoord, UpdateSourceTrigger=PropertyChanged}" Name="y" Height="20" Width="40" Margin="40,81,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</Grid>
</Window>
Here is the code behind. I changed the code to adjust the rectangle size rather than creating a new rectangle every time the values are changed.
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
namespace WpfApp9
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
private double xval = 50;
public double xcoord
{
get=> xval;
set
{
xval = value;
CreateARectangle();
}
}
private double yval = 50;
public double ycoord
{
get => yval;
set
{
yval = value;
CreateARectangle();
}
}
Rectangle rect = null;
public void CreateARectangle()
{
if (rect == null)
{
// Creates a Rectangle
rect = new Rectangle();
rect.Height = ycoord;
rect.Width = xcoord;
// Create a Brush
SolidColorBrush colorbrush = new SolidColorBrush();
colorbrush.Color = Colors.Red;
colorbrush.Opacity = .3;
SolidColorBrush blackBrush = new SolidColorBrush();
blackBrush.Color = Colors.Black;
// Set Rectangle's width and color
rect.StrokeThickness = 1;
rect.Stroke = blackBrush;
// Fill rectangle with color
rect.Fill = colorbrush;
// Add Rectangle to the Grid.
can.Children.Add(rect);
}
else
{
rect.Height = ycoord;
rect.Width = xcoord;
}
}
}
}
As a side note you can also create the rectangle in XAML, directly binding to the textbox values.
<TextBox Text="50" Name="x" Height="20" Width="40" Margin="10,10,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<TextBox Text="50" Name="y" Height="20" Width="40" Margin="10,35,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" RenderTransformOrigin="-0.017,-0.629"/>
<Rectangle Stroke="Black" Fill="#4CFF0000" Margin="60,5,0,0" Width="{Binding ElementName=x, Path=Text, UpdateSourceTrigger=PropertyChanged}" Height="{Binding ElementName=y, Path=Text, UpdateSourceTrigger=PropertyChanged}"/>

WPF Application - Not able to change rectangle properties on MouseDown

I have a simple WPF application which is a window application. There is a Canvas on this window. What I want to do is when I move the mouse on the Canvas It should draw a rectangle on the canvas and next when I press the left mouse button the color of the rectangle should get changed. I am perfectly able to draw a rectangle on mouse move event and also receiving MouseDown event on Rectangle but when I am trying to change the color of this rectangle It is not working. The code is very simple
Here is my xaml file
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Canvas Background="#11FFFFFF" IsHitTestVisible="True" x:Name="overlay" Opacity="1">
</Canvas>
</Grid>
</Window>
and here is my xaml.cs file
namespace WpfApp1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
overlay.MouseMove += OnOverlayMouseMove;
}
private void OnOverlayMouseMove(object sender, MouseEventArgs args)
{
overlay.Children.Clear();
Point ps = args.GetPosition(overlay);
Rectangle rect = new Rectangle
{
Fill = Brushes.LightBlue,
Stroke = Brushes.LightGray,
StrokeThickness = 2,
Width = 100,
Height = 50
};
rect.Opacity = 0.5;
rect.MouseLeftButtonDown += OnRectLeftMouseButtonDown;
rect.Name = "Blue";
Canvas.SetLeft(rect, ps.X - 50);
Canvas.SetTop(rect, ps.Y - 25);
overlay.Children.Add(rect);
}
private void OnRectLeftMouseButtonDown(object sender, MouseEventArgs args)
{
Rectangle rect = sender as Rectangle;
if (rect.Name.Equals("Blue"))
{
rect.Fill = Brushes.Black;
rect.Name = "Black";
}
else
{
rect.Fill = Brushes.LightBlue;
rect.Name = "Blue";
}
args.Handled = true;
}
}
}
The color is not changing because you are creating a new rectangle every time OnOverlayMouseMove is called and setting Fill to LightBlue
You can do something like the following,
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
overlay.MouseMove += OnOverlayMouseMove;
}
private void OnOverlayMouseMove(object sender, MouseEventArgs args)
{
overlay.Children.Clear();
Point ps = args.GetPosition(overlay);
Rectangle rect = new Rectangle
{
Fill = brush,
Stroke = Brushes.LightGray,
StrokeThickness = 2,
Width = 100,
Height = 50
};
rect.Opacity = 0.5;
rect.MouseLeftButtonDown += OnRectLeftMouseButtonDown;
rect.Name = "Blue";
Canvas.SetLeft(rect, ps.X - 50);
Canvas.SetTop(rect, ps.Y - 25);
overlay.Children.Add(rect);
}
private SolidColorBrush brush = Brushes.LightBlue;
private void OnRectLeftMouseButtonDown(object sender, MouseEventArgs args)
{
Rectangle rect = sender as Rectangle;
if (brush == Brushes.LightBlue)
{
brush = Brushes.Black;
}
else
{
brush = Brushes.LightBlue;
}
args.Handled = true;
}
}
I think you need something like this:
public partial class MainWindow : Window
{
private Color normal = Color.FromRgb(255, 0, 0);
private Color active = Color.FromRgb(0, 0, 0);
private SolidColorBrush rectangleBrush;
public MainWindow()
{
InitializeComponent();
rectangleBrush = new SolidColorBrush(normal);
overlay.MouseMove += OnOverlayMouseMove;
}
private void OnOverlayMouseMove(object sender, MouseEventArgs args)
{
overlay.Children.Clear();
Point ps = args.GetPosition(overlay);
Rectangle rect = new Rectangle
{
Fill = rectangleBrush,
Stroke = Brushes.LightGray,
StrokeThickness = 2,
Width = 100,
Height = 50
};
rect.Opacity = 0.5;
rect.MouseLeftButtonDown += OnRectLeftMouseButtonDown;
Canvas.SetLeft(rect, ps.X - 50);
Canvas.SetTop(rect, ps.Y - 25);
overlay.Children.Add(rect);
}
private void OnRectLeftMouseButtonDown(object sender, MouseEventArgs args)
{
Rectangle rect = sender as Rectangle;
if ((rect.Fill as SolidColorBrush).Color == normal) {
rectangleBrush.Color = active;
} else {
rectangleBrush.Color = normal;
}
args.Handled = true;
}
}
If you want use colors from Color struct just replace normal and active vars with "Colors.LightBlue" and "Colors.Black"

How can I move shape created by a button on the canvas in WPF?

I am very new to C# and WPF and would to create a WPF application that draws shapes with a button. The shapes then need to be able to move around the canvas. When I create a shape in the XAML it moves. However I cannot get the one created by the button to move. Could anyone please assist? Below are the XAML and code that i am using.
XAML:
<Window x:Class="All_test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Canvas x:Name="canvas" >
<Button Content="Button" Canvas.Left="250" Canvas.Top="260" Width="75" Click="Button_Click_1" />
<Rectangle x:Name="rect"
Height="100" Width ="100" Fill="red"
MouseLeftButtonDown="rect_MouseLeftButtonDown"
MouseLeftButtonUp="rect_MouseLeftButtonUp"
MouseMove="rect_MouseMove"
Canvas.Left="342" Canvas.Top="110" />
</Canvas>
This is the code I am using to move the red square drawn in XAML. How can I do the same for the green one created by the button?
public partial class MainWindow : Window
{
private bool _isRectDragInProg;
public MainWindow()
{
InitializeComponent();
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
Rectangle rect = new Rectangle();
rect.Fill = new SolidColorBrush(Colors.Green);
rect.Stroke = new SolidColorBrush(Colors.Black);
rect.Height = 100;
rect.Width = 100;
rect.StrokeThickness = 4;
canvas.Children.Add(rect);
InitializeComponent();
}
private void rect_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
_isRectDragInProg = true;
rect.CaptureMouse();
}
private void rect_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
_isRectDragInProg = false;
rect.ReleaseMouseCapture();
}
private void rect_MouseMove(object sender, MouseEventArgs e)
{
if (!_isRectDragInProg) return;
// get the position of the mouse relative to the Canvas
var mousePos = e.GetPosition(canvas);
// center the rect on the mouse
double left = mousePos.X - (rect.ActualWidth / 2);
double top = mousePos.Y - (rect.ActualHeight / 2);
Canvas.SetLeft(rect, left);
Canvas.SetTop(rect, top);
}
You should bind the mouse events for this Rectangle:
private void Button_Click_1(object sender, RoutedEventArgs e)
{
Rectangle rect = new Rectangle();
rect.Fill = new SolidColorBrush(Colors.Green);
rect.Stroke = new SolidColorBrush(Colors.Black);
rect.Height = 100;
rect.Width = 100;
rect.StrokeThickness = 4;
// here
rect.MouseLeftButtonDown += rect_MouseLeftButtonDown;
rect.MouseLeftButtonUp += rect_MouseLeftButtonUp;
rect.MouseMove += rect_MouseMove;
canvas.Children.Add(rect);
// InitializeComponent(); <--- lose the InitializeComponent here, that's should only be called ones.. (in the constructor)
}
Recommendations:
Use the sender parameter to get the current Rectangle.
You can lose the _isRectDragInProg boolean... use the IsMouseCaptured property instead.
For example:
private void rect_MouseMove(object sender, MouseEventArgs e)
{
var rect = (Rectangle)sender;
if (!rect.IsMouseCaptured) return;
// get the position of the mouse relative to the Canvas
var mousePos = e.GetPosition(canvas);
// center the rect on the mouse
double left = mousePos.X - (rect.ActualWidth / 2);
double top = mousePos.Y - (rect.ActualHeight / 2);
Canvas.SetLeft(rect, left);
Canvas.SetTop(rect, top);
}

WPF usercontrol out of bounds of the Grid

I have a WPF app that I'm testing which loads a XML and visualizes it in a usercontrol. Now the issue I'm having is that every time I load my user control the HorizontalAlignment is okay, but the VerticalAlignment doesn't adept to the height size of the usercontrol.
Anyone has an idea how to solve this?
MainWindow.xaml
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:UserControls="clr-namespace:RackBuildingTesT.UserControls" x:Class="RackBuildingTesT.MainWindow"
Title="MainWindow" Height="578" Width="758" SizeChanged="Window_SizeChanged_1">
<Grid>
<DockPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Border DockPanel.Dock="Top" BorderBrush="Black" BorderThickness="1">
<Grid>
<Label Content="Welke rack laden" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<ComboBox x:Name="RackChooser" HorizontalAlignment="Left" Margin="100,0,0,0" VerticalAlignment="Top" Width="120" SelectionChanged="RackChooser_SelectionChanged"/>
</Grid>
</Border>
<Border DockPanel.Dock="Top" BorderBrush="Black" BorderThickness="1">
<Grid x:Name="RackGrid" Margin="0,0,0,0">
</Grid>
</Border>
</DockPanel>
</Grid>
MainWindow.xaml.cs
public MainWindow()
{
InitializeComponent();
LoadRackCombo();
}
private void LoadRackCombo()
{
var files = Directory.GetFiles(Properties.Settings.Default.FilePathXMLRack);
foreach (var item in files)
{
RackChooser.Items.Add(item);
}
}
private void RackChooser_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
this.RackGrid.Children.Clear();
this.Cursor = Cursors.Wait;
if (RackChooser.SelectedIndex == -1)
MessageBox.Show("Select a rack");
else
{
string rackFile = Convert.ToString(RackChooser.Items[RackChooser.SelectedIndex]);
UserControls.RackBuilder r = new UserControls.RackBuilder();
RackGrid.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
RackGrid.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
r.Width = RackGrid.Width;
r.Height = RackGrid.Height;
var _r = TRack.CreateFromXMLFile(rackFile, null);
r.set_Rack(_r);
RackGrid.Children.Add(r);
}
this.Cursor = Cursors.Arrow;
}
private void Window_SizeChanged_1(object sender, SizeChangedEventArgs e)
{
RackGrid.Width = this.Width;
RackGrid.Height = this.Height;
}
RackBuilder.xaml.cs (xaml page is standard WPF usercontrol)
public RackBuilder()
{
InitializeComponent();
}
public TRack fRack { get; set; }
public void set_Rack(TRack value)
{
this.fRack = value;
this.InvalidateVisual();
}
protected override void OnRender(DrawingContext drawingContext)
{
if (this.fRack != null)
{
var xScale = this.Width / this.fRack.Size.Width;
var yScale = this.Height / this.fRack.Size.Height;
var smallest = 0.0;
if (xScale < yScale)
smallest = xScale;
else
smallest = yScale;
foreach (var hole in this.fRack.HolePositions)
{
drawingContext.DrawEllipse(Brushes.Aquamarine, null, new Point(hole.Position.X * xScale, hole.Position.Y * yScale),
hole.Diameter * smallest * 0.5, hole.Diameter * smallest * 0.5);
}
}
}
Result
Instead of adding your Control to a Grid, use the ContentControl and add it to its Content-Property.
It also stretches its child automatically.
I fixed it with putting the MainWindow SizeToContent to WidthAndHeight.

Why does not MouseLeftButtonUp fire in WPF?

Why does not the MouseLeftButtonUp on my Canvas fire in my WPF app?
Here is the XAML:
<Grid Height="300" Width="400">
<Canvas Name="canvas" MouseMove="canvas_MouseMove" MouseLeftButtonUp="canvas_MouseLeftButtonUp" Background="LightGray"/>
</Grid>
And the code:
private bool hasClicked = false;
public Window1()
{
InitializeComponent();
}
private void canvas_MouseMove(object sender, MouseEventArgs e)
{
if (!this.hasClicked)
{
this.Cursor = Cursors.None;
this.canvas.Children.Clear();
this.insertRectangle(false);
}
}
private void insertRectangle(bool filled)
{
Rectangle rect = createRect(filled);
Point pos = Mouse.GetPosition(this.canvas);
Canvas.SetLeft(rect, pos.X);
Canvas.SetTop(rect, pos.Y);
this.canvas.Children.Add(rect);
}
private Rectangle createRect(bool fill)
{
Rectangle rect = new Rectangle();
rect.Height = 50;
rect.Width = 120;
if (fill)
{
rect.Fill = new SolidColorBrush(Colors.Green);
}
else
{
rect.Stroke = new SolidColorBrush(Colors.Green);
}
return rect;
}
private void canvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
this.hasClicked = true;
this.insertRectangle(true);
this.Cursor = Cursors.Arrow;
}
Edit: I have tried adding a background colour to the canvas, but still the event is not fired. It seems like the MouseMove somehow overrides the MouseLeftButtonUp.
Edit2: If I remove the MouseMove event, mouseLeftButtonUp will fire.
Edit3: Bigger code example.
In the insertRectangle method, if I use
Canvas.SetTop(rect, 50);
instead of
Canvas.SetTop(rect, pos.Y);
the events fires just fine.
If you don't set a Background on the canvas, it doesn't seem to pay attention to your mouse events.
Try:
<Grid>
<Canvas Name="canvas"
MouseMove="canvas_MouseMove"
MouseLeftButtonUp="canvas_MouseLeftButtonUp"
Background="White" />
</Grid>
By not clearing the canvas, but instead moving the preview rectangle in the mouseMove method solved the problem.

Categories