How can i make the Canvas in a event visible? - c#

i have following problem, i want to generate a little canvas by a button click, after generating i want to move it by a key press event but i cant see the canvas in the event. How can i make it visible? (In the sourcecode of WPF not in XAML)
public void Button_Click_1(object sender, RoutedEventArgs e)
{
Canvas c = new Canvas();
c.Height = System.Windows.SystemParameters.PrimaryScreenHeight;
c.Width = System.Windows.SystemParameters.PrimaryScreenWidth;
c.Loaded += c_Loaded;
Grid.Children.Add(c);
Canvas ship = new Canvas();
ship.Background = Brushes.Aquamarine;
ship.Height = 30;
ship.Width = 30;
ship.KeyDown += ship_KeyDown;
Canvas.SetTop(ship, 50);
c.Children.Add(ship);
}
void ship_KeyDown(object sender, KeyEventArgs e)
{
canvas.Setleft(ship, canvas.Getleft(ship) +10); //here i can not see the object "ship" :(
}

Use parameter sender:
Canvas ship = (Canvas) sender;

You would need to add you c or ship to the layoutroot`

The easiest way is to add it to a <list> of UIElement and modify it with a foreach-loop

Related

How to make label reappear as soon as it's going out of panel width

I want to make a moving label seem nicer and smoother than just reappearing the whole thing to the left after it has all gone out of panel width .For example label 'Hello' , as soon as 'lo' goes out of bounds in the right I want it to reappear on the left. Is there any possible solution to this ?
Here's the code I have for the label now .
private void timer2_Tick(object sender, EventArgs e)
{
label5.Location = new Point(label5.Location.X + 3, label5.Location.Y);
if (label5.Location.X > this.Width)
{
label5.Location = new Point(0 - label5.Width, label5.Location.Y);
}
}
Try this, using a Label (here, named lblMarquee and a System.Windows.Forms.Timer).
The scrolling time is regulated by both the Timer.Interval and a float Field (marqueeStep).
The Timer.Tick event just calls lblMarquee.Invalidate(), causing the Label control to repaint itself.
When the scrolling text, in relation to its current position, goes beyond the limits of the Label.ClientRectangle, the section of the text which is not visible anymore is painted at start of the Label.ClientArea:
System.Windows.Forms.Timer marqueeTimer = new System.Windows.Forms.Timer();
string marqueeText = string.Empty;
float marqueePosition = 0f;
float marqueeStep = 4f;
private void form1_Load(object sender, EventArgs e)
{
marqueeText = lblMarquee.Text;
lblMarquee.Text = string.Empty;
marqueeTimer.Tick += (s, ev) => { this.lblMarquee.Invalidate(); };
marqueeTimer.Interval = 100;
marqueeTimer.Start();
}
private void lblMarquee_Paint(object sender, PaintEventArgs e)
{
var marquee = sender as Label;
SizeF stringSize = e.Graphics.MeasureString(marqueeText, marquee.Font, -1, marqueeFormat);
PointF stringLocation = new PointF(marqueePosition, (marquee.Height - stringSize.Height) / 2);
stringLength = marquee.ClientRectangle.Width - stringLocation.X;
e.Graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
e.Graphics.DrawString(marqueeText, marquee.Font, Brushes.Black, stringLocation, marqueeFormat);
if (marqueePosition >= marquee.ClientRectangle.Width) marqueePosition = 0f;
if (stringSize.Width + stringLocation.X > marquee.ClientRectangle.Width) {
PointF partialStringPos = new PointF(-stringLength, (marquee.Height - stringSize.Height) / 2);
e.Graphics.DrawString(marqueeText, marquee.Font, Brushes.Black, partialStringPos, marqueeFormat);
}
marqueePosition += marqueeStep;
}
A couple of other implementations you might find useful:
How to follow the end of a text in a TextBox with no NoWrap
How to draw a string on two not adjacent areas
You need to have two label controls to do this, but it's not really that difficult. First, create a backup label and set it's properties to look like label5:
// A backup label for our scrolling label5
private Label label5_backup;
private void Form1_Load(object sender, EventArgs e)
{
label5.Text = "This is a scrolling label!";
// Set label5_backup to look like label5
label5_backup = new Label
{
Size = label5.Size,
Text = label5.Text,
Top = label5.Top,
Visible = false
};
Controls.Add(label5_backup);
timer2.Interval = 1;
timer2.Start();
}
Then, in the Tick event, as soon as our label5 starts to leave the client rectangle, set our backup label to the proper distance from the left of the form so that it starts to appear on the other side. And as soon as label5 is completely off the form, set it's location to match the backup label and then hide the backup label again.
Note that you can just set the Left property instead of creating a new Location point each time, which simplifies the code a little:
private void timer2_Tick(object sender, EventArgs e)
{
label5.Left++;
// If label5 starts to go off the right, show our backup on the left side of the form
if (label5.Right > ClientRectangle.Width)
{
label5_backup.Left = label5.Right - ClientRectangle.Width - label5.Width;
label5_backup.Visible = true;
}
// If label5 is all the way off the form now, set it's location to match the backup
if (label5.Left > ClientRectangle.Width)
{
label5.Location = label5_backup.Location;
label5_backup.Visible = false;
}
}
Also, if you want to make the scrolling smoother, only increment the Left by 1 each time and reduce the timer2.Interval to a third of what it was before (unless it's already at 1).

Selecting image from StackPanel C# UWP (Adding action listener to UIElement and Image to UIElement)

I am using C# and I am creating UWP app.
I am using Windons.Ui.Xaml.Controls.Image and I have created follwoing code which lists my images
UxHelpers.DispatchToASTAThread(
async () =>
{
imageIndex++;
StackPanel stackPanel = new StackPanel();
stackPanel.Children.Add(image);
}
this.Results.Children.Add(stackPanel);
}).Forget();
This is in for loop, and I want when user clicks on certain image to be able to save it.
I have code for saving, I just don't know how to add mouse listener to each image, so that it is marked when I move mouse over it (So user knows that by clicking on it something will happen) and when he clicks I want it to call my function with this pictures index....
I have looked at UIElement but i still can't figure it out.
Thanks!!
We can add the PointerEntered event to the Image control that when the user move mouse over it then we can change the UI. Then we can add the Tapped event to the Image control, if the user click on it, it will be fired.
To get the index of the Image, we can set the index to the Name property of the Image.
For example:
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
StackPanel stackPanel = new StackPanel();
for (int i = 0; i < 3; i++)
{
Windows.Storage.Streams.IRandomAccessStream random = await Windows.Storage.Streams.RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/sun2set.jpg")).OpenReadAsync();
Image image = new Image();
BitmapImage bitmapImage = new BitmapImage();
StackPanel mystackPanel = new StackPanel();
image.Name = i.ToString();
bitmapImage.SetSource(random);
image.Source = bitmapImage;
mystackPanel.Children.Add(image);
image.PointerEntered += Image_PointerEntered;
image.PointerExited += Image_PointerExited;
stackPanel.Children.Add(mystackPanel);
}
this.Results.Children.Add(stackPanel);
}
private void Image_PointerExited(object sender, PointerRoutedEventArgs e)
{
var image = sender as Image;
var parent = VisualTreeHelper.GetParent(image) as StackPanel;
parent.BorderBrush = new SolidColorBrush(Colors.Red);
parent.BorderThickness = new Thickness(0);
image.Tapped -= Image_Tapped;
}
private void Image_PointerEntered(object sender, PointerRoutedEventArgs e)
{
var image = sender as Image;
Debug.WriteLine("The" + image.Name + "is Selected!");
var parent = VisualTreeHelper.GetParent(image) as StackPanel;
parent.BorderBrush = new SolidColorBrush(Colors.Red);
parent.BorderThickness = new Thickness(5);
image.Tapped += Image_Tapped;
}
private void Image_Tapped(object sender, TappedRoutedEventArgs e)
{
var image = sender as Image;
//download the image
}

MouseDown and touch screen

I have a problem with the C# MouseDown event. When I use the touch screen to touch the mouse down label once, whenever I touch next will also trigger the event. But when I use the mouse to click it, all seems to be okay.
Here is my sample code for the label mouse down event:
lblEAForm = new Label();
lblEAForm.Name = "lblEAForm";
lblEAForm.Width = 240;
lblEAForm.Height = 250;
lblEAForm.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
lblEAForm.Margin = new Thickness(20);
lblEAForm.Background = new ImageBrush(new BitmapImage(new Uri("pack://application:,,,/Images/BorangEA.png")));
Grid.SetColumn(lblEAForm, 1);
Grid.SetRow(lblEAForm, 0);
lblEAForm.MouseDown += ShowGUIEAForm;
Here is the function that it should call:
public void msg(object sender, EventArgs e)
{
MessageBox.Show("Clicked");
}
I'm not sure what I'm doing wrong. Can anyone help?

create multiple rectangle dynamically in windows phone

I have created a canvas and I want to let user create rectangle/s on the screen and then user should be able to manipulate it.
I have written the following code -
private TranslateTransform move = new TranslateTransform();
private ScaleTransform resize = new ScaleTransform();
private TransformGroup rectangleTransforms = new TransformGroup();
private Brush stationaryBrush;
private Brush transformingBrush = new SolidColorBrush(Colors.Orange);
private void Button_Click(object sender, RoutedEventArgs e)
{
rect = new Rectangle();
rect.Height = 100;
rect.Width = 100;
SolidColorBrush myBrush = new SolidColorBrush(Colors.Orange);
rect.Fill = myBrush;
LayoutRoot.Children.Add(rect);
rectangleTransforms.Children.Add(move);
rectangleTransforms.Children.Add(resize);
rect.RenderTransform = rectangleTransforms;
// Handle manipulation events.
rect.ManipulationStarted +=
new EventHandler<ManipulationStartedEventArgs>(Rectangle_ManipulationStarted);
rect.ManipulationDelta +=
new EventHandler<ManipulationDeltaEventArgs>(Rectangle_ManipulationDelta);
rect.ManipulationCompleted +=
new EventHandler<ManipulationCompletedEventArgs>(Rectangle_ManipulationCompleted);
}
void Rectangle_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
{
rect.Fill = stationaryBrush;
}
void Rectangle_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
{
stationaryBrush = rect.Fill;
rect.Fill = transformingBrush;
}
void Rectangle_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
move.X += e.DeltaManipulation.Translation.X;
move.Y += e.DeltaManipulation.Translation.Y;
if (e.DeltaManipulation.Scale.X > 0 && e.DeltaManipulation.Scale.Y > 0)
{
resize.ScaleX *= e.DeltaManipulation.Scale.X;
resize.ScaleY *= e.DeltaManipulation.Scale.Y;
}
}
I copied this code from MSDN Library.
I have declared a rectangle object(rect) above.
Now my problem is this code is working fine for one rectangle but I want to give use an option to add another or multiple rectangles.
1.is it possible to create multiple rectangle with same button click event and let the user manipulate each rectangle create or something where he can adjust the rectangle atleast one time after creating it and not afterwards.
Any Help is appreciated.
You'd just have to get the Rectangle instance from the "sender" in the event handler, rather than storing a local copy:
void Rectangle_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
{
var rect = (Rectangle)sender;
rect.Fill = stationaryBrush;
}
The same applies to "move" -- don't use a local variable, but create a new instance in each button click event:
var rectangleTransform = new TransformGroup();
rectangleTransforms.Children.Add(new TranslateTransform());
rectangleTransforms.Children.Add(new ScaleTransform());
rect.RenderTransform = rectangleTransforms;
You can retrieve it in the "ManipulationDelta" handler by casting the RenderTransform property back to the TransformGroup type:
void Rectangle_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
var rect = (Rectangle)sender;
var move = (TransformGroup)rect.RenderTransform;
// etc

how to make user control draggable only from specific places

im working now on a UserControl which ive made draggable using the code below (which is quite known and used). This UserControl looks and is used in a similar to MessageBox (the gray color and the blue rectangle) , the task is to make this UserControl draggable only from the blue rectangle just as any MessageBox , not as its now draggable from any place inside it!
any suggestions on how to be able to do this? thanks in advance!
below the code used to drag the UserControl
public UserControl1(Data data, Settings settings)
{
InitializeComponent();
MouseLeftButtonDown += new MouseButtonEventHandler(root_MouseLeftButtonDown);
MouseLeftButtonUp += new MouseButtonEventHandler(root_MouseLeftButtonUp);
MouseMove += new MouseEventHandler(root_MouseMove);
}
...
private void root_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var element = sender as FrameworkElement;
anchorPoint = e.GetPosition(null);
element.CaptureMouse();
isInDrag = true;
e.Handled = true;
}
private void root_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (isInDrag)
{
var element = sender as FrameworkElement;
element.ReleaseMouseCapture();
isInDrag = false;
e.Handled = true;
}
}
private void root_MouseMove(object sender, MouseEventArgs e)
{
if (isInDrag)
{
var element = sender as FrameworkElement;
currentPoint = e.GetPosition(null);
UIElement parentElement = (UIElement)this.Parent;
maxHeightParent = parentElement.RenderSize.Height;
maxWidthParent = parentElement.RenderSize.Width;
maxHeight = RenderSize.Height;
maxWidth = RenderSize.Width;
//Window.ActualHeightProperty
//element.ActualHeight
transform.X += (currentPoint.X - anchorPoint.X);
transform.Y += (currentPoint.Y - anchorPoint.Y);
this.RenderTransform = transform;
anchorPoint = currentPoint;
}
}
}
Two ways to solve this, which are actually the same way with different syntax:
Via code - in the constructor, instead of
MouseLeftButtonDown += new MouseButtonEventHandler(root_MouseLeftButtonDown);
MouseLeftButtonUp += new MouseButtonEventHandler(root_MouseLeftButtonUp);
MouseMove += new MouseEventHandler(root_MouseMove);
use
myBlueRect.MouseLeftButtonDown +=
new MouseButtonEventHandler(root_MouseLeftButtonDown);`
myBlueRect.MouseLeftButtonUp +=
new MouseButtonEventHandler(root_MouseLeftButtonUp);
myBlueRect.MouseMove += new MouseEventHandler(root_MouseMove);
Via XAML - in the tag of the relevant element that you want to grag from (lets say it's a Grid):
<Grid x:Name="myBlueRect"
MouseLeftButtonDown="root_MouseLeftButtonDown"
MouseLeftButtonUp="root_MouseLeftButtonUp"
MouseMove="root_MouseMove"
.../>
Two basic options I think about:
Inside your UserControl make the rectangle a Border (or other control), and put the events on this Border and not on the UserControl.
If from some reason you do want the events to be on the UserControl, put a Hidden Border on the place of the rectangle, and in the event do the dragging only if the mouse is over this Border.

Categories