WPF dynamic Textbox shows in different positions - c#

This is some interesting behavior and maybe someone could shed some light on it. I have a Grid that is the size of my Screen and is transparent. In that I generate a TextBox dynamically, but for whatever reason that TextBox element slides down on the screen 4 times and then reappears on top again just to do the same again.... Any ideas how I can keep that locked in one place? Btw the same happens when I use a canvas instead of loading it into the grid...
double x_co = Convert.ToDouble(x_coord);
double y_co = Convert.ToDouble(y_coord);
TextBox txtNumber = new TextBox();
txtNumber.Name = "L" + x_coord.ToString();
txtNumber.Height = 85;
txtNumber.Width = 200;
txtNumber.Opacity = 1;
txtNumber.FontSize = 42;
txtNumber.SetValue(TextBlock.FontWeightProperty, FontWeights.Bold);
txtNumber.Background = System.Windows.Media.Brushes.Transparent;
txtNumber.BorderBrush = System.Windows.Media.Brushes.Transparent;
txtNumber.HorizontalAlignment = HorizontalAlignment.Left;
txtNumber.VerticalAlignment = VerticalAlignment.Top;
txtNumber.Foreground = new SolidColorBrush(Colors.White);
txtNumber.Margin = new Thickness(x_co, y_co, 0, 0);
RootGrid.Children.Add(txtNumber);
RootGrid.RegisterName(txtNumber.Name, txtNumber);
string tx_num = "L" + x_coord.ToString();
txtNumber= (TextBox)this.RootGrid.FindName(tx_num);
txtNumber.Text = action;
And thats the XAML I load it into:
<Window x:Name="MyPanel" x:Class="C1.hud"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="hud" Height="1080" Width="1920" AllowsTransparency="True" WindowStyle="None">
<Window.Background>
<SolidColorBrush Opacity="0.0" Color="White"/>
</Window.Background>
<Grid x:Name="RootGrid" Margin="0,0,0,0"/>

Related

How to fix DoubleAnimation for rotation of an image?

I am trying to rotate an image on an EventHandler, for an Event that i created. The Event Handler works perfectly fine. Yet the image does not rotate and I do not know what I am missing.
This UserControl is not displayed like this, but in a Grid of another UserControl.
<UserControl x:Class="Mabri.Module.P83.View.SchematicSystemView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Mabri.Module.P83.View"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Image x:Name="drehteller" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</UserControl>
This is the code behind the XAML, at first I tried having this in a separat class, if this is possible it would be even better, but at the moment I am just trying to get this running.
{
private System.Windows.Controls.Image drehteller_image;
private int currentAngle = 0;
public SchematicSystemView()
{
EventAggregator.SubscribeEvent(this);
InitializeComponent();
drehteller_image = new System.Windows.Controls.Image()
{
Stretch = Stretch.Uniform,
Source = new BitmapImage(new Uri("pack://application:,,,/Mabri.Module.P83;Component/Images/drehteller_unbestueckt.png")),
RenderTransform = new RotateTransform()
};
drehteller.Source = drehteller_image.Source;
}
public void OnEventHandler(DrehtellerMoved e)
{
EventAggregator.PublishEvent(new LogInfo
{
Title = "Should rotate",
Summary = "The drehteller should rotate now",
Detail = "The drehteller should rotate " + currentAngle + " is the current angle",
LogLevel = LogLevel.Information
});
int steps = e.steps;
double timeforonestep = e.speed / e.steps;
int angle = steps * 72;
int angle_to_reach = currentAngle + angle;
Storyboard storyboard = new Storyboard();
storyboard.Duration = new Duration(TimeSpan.FromSeconds(timeforonestep * steps));
DoubleAnimation rotateAnimation = new DoubleAnimation()
{
From = currentAngle,
To = currentAngle + angle,
Duration = storyboard.Duration
};
Storyboard.SetTarget(rotateAnimation, drehteller);
Storyboard.SetTargetProperty(rotateAnimation, new PropertyPath("(UIElement.RenderTransform).(RotateTransform.Angle)"));
storyboard.Children.Add(rotateAnimation);
storyboard.Begin();
currentAngle = angle_to_reach;
}
}
In the testing case e.steps equals 1 and e.speed equals 10.0.
I expected the image to turn for 72 degrees, but for some reasons nothing happens, except for the LogMessage at the beginning of the handler.
First, assign a RotateTransform to the RenderTransform property of the Image. Otherwise it can't be animated.
<Image x:Name="drehteller" HorizontalAlignment="Center" VerticalAlignment="Center"
RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<RotateTransform/>
</Image.RenderTransform>
</Image>
Then instead of setting From and To just set By. And drop the Storyboard and start the animation directly on the control's RenderTransform
var animation = new DoubleAnimation
{
By = angle,
Duration = TimeSpan.FromSeconds(...)
};
drehteller.RenderTransform.BeginAnimation(RotateTransform.AngleProperty, animation);
Finally, do not create the intermediate Image element. That is redundant.
drehteller.Source = new BitmapImage(new Uri("..."));

Can WPF window contain a child ?

I have a WPF window:
<Window x:Class="Snapit.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" WindowState="Maximized"
ShowInTaskbar="True" AllowsTransparency="True" WindowStyle="None" Opacity="0.1"
BorderThickness="25" BorderBrush="Black" Name="myWindow">
<Grid Name="myGrid">
</Grid>
</Window>
And I have a rectangle
System.Windows.Shapes.Rectangle myRect = new System.Windows.Shapes.Rectangle();
myRect = new System.Windows.Shapes.Rectangle();
myRect.Stroke = System.Windows.Media.Brushes.Yellow;
myRect.Fill = System.Windows.Media.Brushes.Black;
myRect.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
myRect.VerticalAlignment = VerticalAlignment.Center;
myRect.Height = 50;
myRect.Width = 50;
myRect.Opacity = 100;
myWindow.AddChild(myRect);
But I am not able to add the rectangle as a child and the error come as :
{"'The invocation of the constructor on type 'Snapit.MainWindow' that matches the specified binding constraints threw an exception.' Line number '3' and line position '9'."}
I dont understand where I am going wrong. Thanks!!
Your window can have only one child, and it's your Grid...
If you want to do it, you should change
myWindow.AddChild(myRect);
to
myGrid.AddChild(myRect);
But, why didn't you use the xaml to write your rectangle ? It will be more clean to read it...
Add it to your Layout Grid not to Window,
Change this line,
From :myWindow.AddChild(myRect);
To :myGrid.AddChild(myRect);
Final Code:
System.Windows.Shapes.Rectangle myRect = new System.Windows.Shapes.Rectangle();
myRect = new System.Windows.Shapes.Rectangle();
myRect.Stroke = System.Windows.Media.Brushes.Yellow;
myRect.Fill = System.Windows.Media.Brushes.Black;
myRect.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
myRect.VerticalAlignment = VerticalAlignment.Center;
myRect.Height = 50;
myRect.Width = 50;
myRect.Opacity = 100;
myGrid.AddChild(myRect);

When typing text in textbox, keep background constant

I'm writing a program that starts out with requiring a certain amount of lines of text and for that I use a TextBox. To make the program look nice, I put a background image on the form. Now I don't want the TextBox to put a large white block on the image, so for that I made the TextBox have a transparent background. But here's the problem: as soon as I start putting text in the TextBox, the lines that have text will revert back to the white background that I don't want. So how can I stop my program from doing that?
I can't post images yet, so I'll just use links:
This image shows the background as I have it and how I want it to be:
This image shows what happens when I start typing:
I want the background to just remain the same while I type (of course the text colour should then be lighter, but the textbox.forecolor seems to have no effect.
So below is the code I have so far, I hope you can help me, I'm still quite new to this :)
public class NieuwSpel : Form
{
Label spelerslijst, nummer;
TextBox spelersInput, spelnr;
Button OK;
public NieuwSpel()
{
this.BackgroundImage = WeerwolvenvanWakkerdam.Properties.Resources.Background_NieuwSpel;
this.FormBorderStyle = FormBorderStyle.Fixed3D;
spelerslijst = new Label();
spelerslijst.Location = new Point(10, 10);
spelerslijst.Text = "Voer hier de spelerslijst in:";
spelerslijst.Width = 200;
spelerslijst.BackColor = Color.Transparent;
spelerslijst.ForeColor = Color.White;
this.Controls.Add(spelerslijst);
spelersInput = new CustomTextBox();
spelersInput.Location = new Point(10, 40);
spelersInput.Size = new Size(200, 300);
spelersInput.Multiline = true;
spelersInput.BackColor = Color.FromArgb(100, 100, 100, 100);
spelersInput.ForeColor = Color.White;
spelersInput.GotFocus += this.setColour;
this.Controls.Add(spelersInput);
OK = new Button();
OK.Text = "Start Spel!";
OK.Location = new Point(110, 430);
OK.Click += this.Start;
this.Controls.Add(OK);
nummer = new Label();
nummer.Text = "Spelnummer:";
nummer.Width = 75;
nummer.Location = new Point(10, 360);
nummer.BackColor = Color.Transparent;
nummer.ForeColor = Color.White;
this.Controls.Add(nummer);
spelnr = new CustomTextBox();
spelnr.Width = 50;
spelnr.Height = 20;
spelnr.Location = new Point(90, 360);
spelnr.BackColor = Color.FromArgb(100, 100, 100, 100);
spelnr.ForeColor = Color.White;
this.Controls.Add(spelnr);
}
public void setColour(object o, EventArgs ea)
{
((CustomTextBox)o).BackColor = Color.FromArgb(100, 100, 100, 100);
}
}
public partial class CustomTextBox : TextBox
{
public CustomTextBox()
{
SetStyle(ControlStyles.SupportsTransparentBackColor |
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.ResizeRedraw |
ControlStyles.UserPaint, true);
}
}
This probably won't be easy in WinForms. If you're just messing around on your own and trying to learn, you might want to consider playing around with WPF. A lot of people still have to deal with WinForms, but I've developed in both and WPF definitely supersedes it.
It can provide the desired effect out-of-the-box:
<Window x:Class="SampleWpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:l="clr-namespace:SampleWpf"
Title="MainWindow" Height="250" Width="400" >
<Window.Background>
<ImageBrush ImageSource="images.jpg" />
</Window.Background>
<Grid>
<TextBox Margin="5" Background="Transparent" Text="HELLO THERE!"
FontSize="20" FontWeight="Bold" Foreground="White" />
</Grid>
</Window>

How to add text to the shapes in WPF

I am drawing Circle on an WPF window. The problem is that I am unable add Text to the Circle. The code is given below:
public Graphics()
{
InitializeComponent();
StackPanel myStackPanel = new StackPanel();
Ellipse myel = new Ellipse();
SolidColorBrush mscb = new SolidColorBrush();
mscb.Color = Color.FromArgb(255, 255, 0, 0);
myel.Fill = mscb;
myel.StrokeThickness = 2;
myel.Stroke = Brushes.Black;
myel.Width = 100;
myel.Height = 100;
//string str = "hello";
myStackPanel.Children.Add(myel);
this.Content = myStackPanel;
}
Please help me in this regard.
Shapes are simply shapes, if you want to add text then add both the shape and a TextBlock with your text to a common container which lays them on top of each other, e.g. a Grid without rows or columns.
In XAML:
<Grid>
<Ellipse Width="100" .../>
<TextBlock Text="Lorem Ipsum"/>
</Grid>
C#
var grid = new Grid();
grid.Children.Add(new Ellipse { Width = 100, ... });
grid.Children.Add(new TextBlock { Text = "Lorem Ipsum" });
Or you can use direct positioning in a Canvas if you prefer direct control over the draw position:
My sample defines a UI control that draws rectangles with text in it:
XAML:
<UserControl x:Class="DrawOnCanvas"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:MySample"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Canvas x:Name="DrawCanvas" Height="30"/>
</Grid>
Code behind:
// You might e.g. call this in the constructor of DrawOnCanvas
internal void DrawRectWithText()
{
var rect = new System.Windows.Shapes.Rectangle();
rect.Stroke = new SolidColorBrush(Colors.Black);
rect.Fill = new SolidColorBrush(Colors.Beige);
rect.Width = 100;
rect.Height = 100;
// Use Canvas's static methods to position the rectangle
Canvas.SetLeft(rect, 100);
Canvas.SetTop(rect, 100);
var text = new TextBlock()
{
Text = task.Title,
};
// Use Canvas's static methods to position the text
Canvas.SetLeft(text, 90);
Canvas.SetTop(text, 90);
// Draw the rectange and the text to my Canvas control.
// DrawCanvas is the name of my Canvas control in the XAML code
DrawCanvas.Children.Add(rect);
DrawCanvas.Children.Add(text);
}

Dynamically create Rectange in silverlight?

I am trying to create Rectangle programmaticallyin silverlight as fallows.
C#
private Boolean Working = false;
const int scale = 4;
const int size = 50;
Int32[] data = new Int32[size];
Rectangle[] lines = new Rectangle[size];
private void button1_Click(object sender, RoutedEventArgs e)
{
canvas1.Children.Clear();
for (int i = 0; i < data.Length; i++)
{
data[i] = i;
lines[i] = new Rectangle()
{
Height=i*scale,
Width = 10,
StrokeThickness=5,
Stroke = new SolidColorBrush(Colors.Red),
Name=i.ToString(),
};
canvas1.Children.Add(lines[i]);
}
}
Now the problem is that all the rectangle are created with the same height and width?.
XAML
<UserControl x:Class="SilverlightApplication1.MainPage"
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"
mc:Ignorable="d"
d:DesignHeight="500" d:DesignWidth="500">
<Canvas x:Name="canvas2" Background="White">
<Canvas x:Name="canvas1" Background="White"></Canvas>
<Button Content=" Generate" Height="38" Name="button1" Width="75" Click="button1_Click" Margin="0,352,245,24" HorizontalAlignment="Right" Canvas.Left="12" Canvas.Top="85" />
<Button Content="Shuffle" Height="38" HorizontalAlignment="Left" Name="button2" Margin="12,352,0,24" Click="button2_Click_1" Canvas.Left="81" Canvas.Top="85" Width="71" />
<Button Canvas.Left="181" Canvas.Top="437" Content="Bubble Sort" Height="38" Name="button3" Width="109" Click="button3_Click" />
</Canvas>
</UserControl>
Screenshot
Actually, everything works fine. All rectangles have different height. But you forget to move them, so they start overlapping. Change a little code and you'll see:
lines[i] = new Rectangle()
{
Height = i * scale,
Width = 10,
StrokeThickness = 5,
Stroke = new SolidColorBrush(Colors.Red),
Name = i.ToString(),
};
lines[i].Margin = new Thickness(11 * i, 0, 0, 0);
Result

Categories