Drawing lines in code using C# and WPF - c#

I'm trying to create a digital clock display using 7 segment displays. I can draw lines in XAML by using code like this:
<Line Name="line7" Stroke="Black" StrokeThickness="4" X1="10" X2="40" Y1="70" Y2="70" Margin="101,-11,362,250" />
But when I try to do it in code(from MainWindow()), it doesn't work:
Line line = new Line();
Thickness thickness = new Thickness(101,-11,362,250);
line.Margin = thickness;
line.Visibility = System.Windows.Visibility.Visible;
line.StrokeThickness = 4;
line.Stroke = System.Windows.Media.Brushes.Black;
line.X1 = 10;
line.X2 = 40;
line.Y1 = 70;
line.Y2 = 70;
The idea is I can draw 7 lines, then toggle their visibility as required for different numbers. I'm sure this can be done many ways, but why can't I draw lines in code like this?

Is that your entire drawing code? If so, you need to add the line object to your surface. If you're using a Canvas for example:
myCanvas.Children.Add(line);
This will add your line to your canvas. At the moment, you're just creating the line but not putting it anywhere.
You can find more information on drawing in WPF on this MSDN page.

public class Cls_Barriere
{
// animazione periferica
public static void LineAnimation(Line _line,String _colore)
{
Storyboard result = new Storyboard();
Duration duration = new Duration(TimeSpan.FromSeconds(2));
ColorAnimation animation = new ColorAnimation();
animation.RepeatBehavior = RepeatBehavior.Forever;
animation.Duration = duration;
switch (_colore.ToUpper())
{
case "RED":
animation.From = Colors.Red;
break;
case "ORANGE":
animation.From = Colors.Orange;
break;
case "YELLOW":
animation.From = Colors.Yellow;
break;
case "GRAY":
animation.From = Colors.DarkGray;
break;
default:
animation.From = Colors.Green;
break;
}
animation.To = Colors.Gray;
Storyboard.SetTarget(animation, _line);
Storyboard.SetTargetProperty(animation, new PropertyPath("(Line.Stroke).(SolidColorBrush.Color)"));
result.Children.Add(animation);
result.Begin();
}
}
//***************************************************************************
public partial class MainPage : UserControl
{
public Line _line;
public MainPage()
{
InitializeComponent();
Canvas.MouseLeftButtonDown += Canvas_MouseLeftButtonDown;
Canvas.MouseLeftButtonUp += Canvas_MouseLeftButtonUp;
}
void Canvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
_line.X2 = e.GetPosition(this.Canvas).X;
_line.Y2 = e.GetPosition(this.Canvas).Y;
_line.Loaded += _line_Loaded;
Canvas.Children.Add(_line);
}
void _line_Loaded(object sender, RoutedEventArgs e)
{
Cls_Barriere.LineAnimation(sender as Line, "RED");
}
void Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
_line = new Line();
_line.Stroke = new SolidColorBrush(Colors.White);
_line.StrokeThickness = 5;
_line.StrokeStartLineCap = PenLineCap.Round;
_line.StrokeEndLineCap = PenLineCap.Round;
_line.StrokeDashCap = PenLineCap.Round;
_line.X1 = e.GetPosition(this.Canvas).X;
_line.Y1= e.GetPosition(this.Canvas).Y;
}

Related

How can i add more than 1 polyline in canvas?

I am using C# WPF to draw 10 polylines on touch screen. Yet, it got an error
"Argument expception was unhandled An unhandled exception of type
'System.ArgumentException' occurred in PresentationCore.dll
Additional information: Specified Visual is already a child of another
Visual or the root of a CompositionTarget."
for the line
canvas.Children.Add(freeline); in private void canvas_TouchDown
when I drew the second line. I could successfully drew one line, but
when I started to draw the second line, it got the mentioned error
public partial class MainWindow : Window
{
//List<Point> list = new List<Point>();
Polyline freeline = new Polyline();
bool isMouseDown = false; //mouse
Color[] colours = new Color[10] {Colors.White, Colors.Yellow,
Colors.Green,Colors.LightBlue, Colors.LightGreen,
Colors.LightCyan, Colors.LightGray, Colors.LightPink,
Colors.Purple, Colors.Red};
// Store the active lines, each of which corresponds to a place
// the user is currently touching down.
Dictionary<int, Line> movingLines = new Dictionary<int, Line>();
Line line = new Line();
int counter = 0;
public MainWindow()
{
InitializeComponent();
}
private void canvas_TouchDown(object sender, TouchEventArgs e)
{
counter = (counter + 1) % 10;
Line line = new Line();
// line.StrokeThickness = e.GetTouchPoint().Size;
// line.Stroke = new SolidColorBrush(colours[counter]);
// Position the line at the touch-down point.
TouchPoint touchPoint = e.GetTouchPoint(canvas);
line.X1 = touchPoint.Position.X;
line.Y1 = touchPoint.Position.Y;
line.X2 = line.X1;
line.Y2 = line.Y1;
movingLines[e.TouchDevice.Id] = line;
// Add the line to the Canvas.
//canvas.Children.Add(line);
// list_store_point_touch(touchPoint.Position.X, touchPoint.Position.Y);
canvas.Children.Add(freeline);
freeline.StrokeThickness = 4;
freeline.Stroke = new SolidColorBrush(colours[counter]);
//e.GetTouchPoint()
//for (int counter = 0; counter < touchPoint.Position.X ; counter++)
//{
// canvas.Children.Add(freeline);
// freeline.StrokeThickness = 4;
// freeline.Stroke = new SolidColorBrush(colours[counter]);
//}
/* for (int i = 0; i < handwritings.Points.Count - 1; i++)
{
drawingContext.DrawLine(new Pen(Brushes.Yellow, 3),
handwritings.Points[i], handwritings.Points[i + 1]);
} */
}
private void canvas_TouchMove(object sender, TouchEventArgs e)
{
// Get the line that corresponds to the current touch-down.
line = movingLines[e.TouchDevice.Id];
// Move it to the new touch-down point.
TouchPoint touchPoint = e.GetTouchPoint(canvas);
line.X2 = touchPoint.Position.X;
line.Y2 = touchPoint.Position.Y;
list_store_point_touch(touchPoint.Position.X, touchPoint.Position.Y);
}
private void canvas_TouchUp(object sender, TouchEventArgs e)
{
movingLines.Remove(e.TouchDevice.Id);
}
private void list_store_point_touch(double X, double Y)
{
Point point = new Point(X,Y);
freeline.Points.Add(point);
}
private void canvas_MouseDown(object sender, MouseButtonEventArgs e)
{
isMouseDown = true;
counter = (counter + 1) % 10;
line = new Line();
line.StrokeThickness = 4;
line.Stroke = new SolidColorBrush(colours[counter]);
// Position the line at the mouse down point.
Point mousePoint = e.GetPosition(canvas);
line.X1 = mousePoint.X;
line.Y1 = mousePoint.Y;
line.X2 = line.X1;
line.Y2 = line.Y1;
//Add the line to the Canvas.
canvas.Children.Add(freeline);
freeline.StrokeThickness = 4;
freeline.Stroke = new SolidColorBrush(colours[counter]);
//canvas.Children.Add(line);
}
Don't reuse the same Polyline instance.
Remove the line:
Polyline freeline = new Polyline();
When you need to draw yet another Polyline, create new one and draw it.
The error is self explanatory you are adding the same freeline more than once to the VisualTree. You need to use a factory method of some kind in order to always get new instances of Polyline before adding to the canvas.Children collection

wp8 writeablebitmap doesn't render

I try to render some elements on writeable bitmap. It works when rendering textblock but not something else for example rectangle. Why so?
void bm_ImageOpened(object sender, RoutedEventArgs e)
{
WriteableBitmap wbm = new WriteableBitmap((BitmapImage)sender);
TextBlock tb = new TextBlock();
tb.FontSize = 40;
tb.Text = "text";
Rectangle rt = new Rectangle();
rt.Width = 50;
rt.Width = 30;
rt.Fill = new SolidColorBrush(Colors.Red);
TranslateTransform tf = new TranslateTransform();
tf.X = 100;
tf.Y = 100;
wbm.Render(tb, tf); //this works
wbm.Render(rt, tf); //this not
wbmi.Invalidate();
}
You are trying to render a Rectangle with Height = 0 - you have defined its Width twice.
I suppose it should look like this:
rt.Width = 50;
rt.Height = 30;

Cannot set Opacity property on ScatterViewItem after an animation has been performed

I am currently removing an element from the user interface by fading it out. This works as expected.
public void HideShape()
{
if (this.TangibleShape != null)
{
DoubleAnimation animation = new DoubleAnimation();
animation.From = 1.0;
animation.To = 0.0;
animation.AutoReverse = false;
animation.Duration = TimeSpan.FromSeconds(1.5);
Storyboard s = new Storyboard();
s.Children.Add(animation);
Storyboard.SetTarget(animation, this.TangibleShape.Shape);
Storyboard.SetTargetProperty(animation, new PropertyPath(ScatterViewItem.OpacityProperty));
s.Begin(this.TangibleShape.Shape);
s.Completed += delegate(object sender, EventArgs e)
{
// call UIElementManager to finally hide the element
UIElementManager.GetInstance().Hide(this.TangibleShape);
};
}
}
The problem is that I want to set the opacity to 1 again in some cases but the TangibleShape.Shape (it's a ScatterViewItem) ignores the command. If I fade out again, the element becomes visible and immediately starts fading out. I don't know how to fix this problem. Does anyone have a hint for me?
public void HideShape()
{
if (this.TangibleShape != null)
{
DoubleAnimation animation = new DoubleAnimation();
animation.From = 1.0;
animation.To = 0.0;
animation.AutoReverse = false;
animation.Duration = TimeSpan.FromSeconds(1.5);
animation.FillBehavior = FillBehavior.Stop; // needed
Storyboard s = new Storyboard();
s.Children.Add(animation);
Storyboard.SetTarget(animation, this.TangibleShape.Shape);
Storyboard.SetTargetProperty(animation, new PropertyPath(ScatterViewItem.OpacityProperty));
s.Completed += delegate(object sender, EventArgs e)
{
// call UIElementManager to finally hide the element
UIElementManager.GetInstance().Hide(this.TangibleShape);
this.TangibleShape.Shape.Opacity = 0.0; // otherwise Opacity will be reset to 1
};
s.Begin(this.TangibleShape.Shape); // moved to the end
}
}
Answer found here: http://social.msdn.microsoft.com/Forums/en-US/7d33ca82-2c02-4004-8b37-47edf4cca34e/scatterviewitem-and-

Trouble with sounds in xna

I have two main pages, GamePage (where all the code to play the game is in), and Mainpage (which is the title screen). What I want to be able to do is play music on the title screen (mainpage.xaml)
I have tried using the content.load method like I have done in the gamepage.xaml. But that does not work, it comes up with a null exception. I have also tried putting it in the section you can see in the screenshot entitled MazeEscapePhoneSilveright, but when i try to run it; the error unexpected characters in the sound file comes up.
How can I play music on the mainpage.xaml, nothing I've tried seems to:
Codebehind mainpage.xaml:
public partial class MainPage : PhoneApplicationPage
{
// Constructor
ContentManager contentManager;
MediaElement player = null;
Popup nameEntry = new Popup();
bool gameMusic;
bool mazeStart = true;
TextBox txtNameEntry = new TextBox();
SoundEffect theme_music;
SoundEffectInstance theme_music_Instance;
SoundEffect zap;
SoundEffectInstance zapInstance;
public MainPage()
{
InitializeComponent();
//SharedGraphicsDeviceManager.Current.GraphicsDevice.SetSharingMode(true);
//Plays the music through a mediaplayer, and a public boolean value.
if (App.Current.Resources.Contains("mediaPlayer"))
{
player = App.Current.Resources["mediaPlayer"] as MediaElement;
player.Source = new Uri("./MazeEscapePhoneSilverightLibContent/Media/magic_wav_file", UriKind.Relative);
}
gameMusic = ((App)Application.Current).gameMusic;
if (gameMusic) player.Play();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (((App)Application.Current).gameMusic)
{
//theme_music = this.contentManager.Load<SoundEffect>("Media/magic_wav_file");
//theme_music_Instance = theme_music.CreateInstance();
}
}
//method runs when "Start Game" button is pressed
private void btnStartGame_Click(object sender, RoutedEventArgs e)
{
if (gameMusic)
{
player.Play();
}
#region CREATE AND DISPLAY POP UP
Border border = new Border();
border.BorderBrush = new SolidColorBrush(Colors.White);
border.BorderThickness = new Thickness(10);
StackPanel myStackPanel = new StackPanel();
myStackPanel.Background = new SolidColorBrush(Colors.Black);
//Textblock containing the name you input and its properties.
//txtNameEntry.Text = Microsoft.Phone.Info.DeviceExtendedProperties.GetValue("DeviceName").ToString();
txtNameEntry.Text = "Player 1";
txtNameEntry.Width = 350;
txtNameEntry.Height = 100;
txtNameEntry.MaxLength = 10;
txtNameEntry.FontFamily = new FontFamily("Comis Sans MS");
txtNameEntry.FontSize = 48.0;
txtNameEntry.Foreground = new SolidColorBrush(Colors.Orange);
txtNameEntry.Background = new SolidColorBrush(Colors.LightGray);
txtNameEntry.BorderBrush = new SolidColorBrush(Colors.LightGray);
//The ok button, which then allows you to procede into the game.
Button btnNameEntryOK = new Button();
btnNameEntryOK.Content = "Ok";
btnNameEntryOK.Background = new SolidColorBrush(Colors.Orange);
btnNameEntryOK.FontFamily = new FontFamily("Comic Sans Ms");
btnNameEntryOK.FontSize = 25.0;
btnNameEntryOK.Width = 180;
btnNameEntryOK.Height = 70;
btnNameEntryOK.Click += new RoutedEventHandler(btnNameEntryOK_Click);
btnNameEntryOK.Margin = new Thickness(10);
//Place these in the order you want them to be renderd to the screen.
myStackPanel.Children.Add(txtNameEntry);
myStackPanel.Children.Add(btnNameEntryOK);
border.Child = myStackPanel;
nameEntry.Child = border;
//set screen position of pop up
nameEntry.VerticalOffset = 100.0;
nameEntry.HorizontalOffset = 50.0;
//open pop up
nameEntry.IsOpen = true;
#endregion
if (nameEntry.IsOpen == false && mazeStart == true)
{
player.Stop();
}
}
void btnNameEntryOK_Click(object sender, RoutedEventArgs e)
{
((App)Application.Current).playerName = txtNameEntry.Text;
nameEntry.IsOpen = false;
mazeStart = true;
player.Stop();
NavigationService.Navigate(new Uri("/GamePage.xaml", UriKind.Relative));
}
private void btnOptions_Click(object sender, RoutedEventArgs e)
{
nameEntry.IsOpen = false;
NavigationService.Navigate(new Uri("/Options.xaml", UriKind.Relative));
}
Screenshot of the solution explorer:

Using wpf to animate ellipses consequently

I have to implement a road junction simple program. The junction's image is set as the Background Property of WPF Grid and I have ArrayLists inside a Queue to represent the color of each car, origin street and destination street.
Now, I need to animate the cars as moving ellipses and I need each car to start its movement after the privious car gets out of the screen.
I am using the following code but it only animates first car.
What is the solution?
private void button1_Click(object sender, RoutedEventArgs e)
{
for (int i = 0; i < queue.Count; i++)
{
ArrayList car = (ArrayList)queue[i];
int id = Convert.ToInt32(car[0]);
int color = Convert.ToInt32(car[1]);
int from= Convert.ToInt32(car[2]);
int to = Convert.ToInt32(car[3]);
Ellipse myEllipse = new Ellipse();
if (color == 0)
{
myEllipse.Stroke = System.Windows.Media.Brushes.Green;
myEllipse.Fill = System.Windows.Media.Brushes.Green;
}
else {
myEllipse.Stroke = System.Windows.Media.Brushes.Blue;
myEllipse.Fill = System.Windows.Media.Brushes.Blue;
}
myEllipse.HorizontalAlignment = HorizontalAlignment.Left;
myEllipse.VerticalAlignment = VerticalAlignment.Center;
myEllipse.Width = 45;
myEllipse.Height = 45;
myGrid.Children.Add(myEllipse);
DoubleAnimation da = new DoubleAnimation();
da.From = from;
da.To = to;
da.Duration = new Duration(TimeSpan.FromSeconds(1));
TranslateTransform tt = new TranslateTransform();
myEllipse.RenderTransform = tt;
tt.BeginAnimation(TranslateTransform.XProperty, da);
}
}
In WPF animation is is organized in other way.
I would suggest you to look at Storyboard. Hope this will help you.

Categories