PictureBox background ignoring WPF UserControl - c#

I want to create a Checkers Board with animation on tiles.
In order to do so I created a rectangle WPF UserControl to represent the tiles.
on top of the tiles I'm using a PictureBox with a picture of red/black piece.
when creating and adding the tiles and after that the PictureBoxes I can't see the PictureBoxes because they are behind the tiles.
(if I reverse the order of the creation and adding of the elements I see the pictures above the tiles but the transparent background of the PictureBoxes shows me the form background like it ignores the UserControl beneath it.
for better explanation I attached a photo (I set the form's background to green for better understanding)
also here are the code parts I think are relevant
the WPF UserControl (named UserControlCell) Xaml
<Grid>
<Rectangle Fill="White" HorizontalAlignment="Left" Height="50" Width="50"
VerticalAlignment="Top" Name="myRect"/>
</Grid>
Each tile is treated that way
ElementHost eh = new ElementHost();
UserControlCell square = new UserControlCell ;
square.Size = new Size(someWidth, someHeight);
eh.Size = new Size(someWidth, someHeight);
eh.Location = new System.Drawing.Point(xCoordinate,yCoordinate);
if ((i + j) % 2 == 0)
square.BackColor = System.Drawing.Color.Black;
else
square.BackColor = System.Drawing.Color.White;
eh.BackColor = Color.Transparent;
eh.Child = square;
Controls.Add(eh);
and for each PictureBox
PictureBox pb = new PictureBox();
pb.Image = relevantImage;
pb.Size = new Size(someWidth, someHeight);
pb.Location = new System.Drawing.Point(xCoordinate,yCoordinate);
pb.TabStop = false;
pb.Visible = true;
pb.BackColor = Color.Transparent;
pb.Refresh();
Controls.Add(pb);
what could be the problem that causes the picture box to think that it's background is the form instead of the tiles (or why does adding them in opposite order making me not seeing the PictureBoxes at all)

Related

Adding texts to flipped System.Windows.Controls Image

I have a wpf image and want to flip it then add to some texts to the image. My below code flips the image but when i add some texts to the image after flipping, the texts also is flipped. How can i avoid this situation ?
//Rotate image in xaml, named 'shipBackImage'
shipBackImage.RenderTransformOrigin = new Point(0.5, 0.5);
ScaleTransform flipTransform = new ScaleTransform();
flipTransform.ScaleX = -1;
shipBackImage.RenderTransform = flipTransform;
//Below method 'SetComponentsOnImage' adds some texts to the image.
shipBackImage.Source = ImageHandler.GetInstance().SetComponentsOnImage((RenderTargetBitmap)shipBackImage.Source, BitmapType.Back);
I expected no rotation to texts

Lowering Background Image of a Panel in C# WinForms

I am trying to build a piano and i have a panel that is designed to house the musical staffs as a background image of this panel.
I have tried to apply these as a Picture Box but this hindered a lot of my other features of this piano. These are the current settings that are related to this particular panel:
this.BorderStyle = BorderStyle.FixedSingle;
this.Size = new Size(750, 75)
this.Location = new Point(125, 75);
this.Anchor = AnchorStyles.None;
this.BackgroundImage = Image.FromFile("..\\..\\..\\Notes-Images\\Notes-Images\\staff2.bmp");
this.Visible = true;
I need to find a way how to actually have control on the location of where the background image is placed so as to lower it from the top left of the panel

How can you outline an ellipse without using stroke property?

What I really want is a way to have a negative stroke Thickness value on a WPF shape such as an ellipse, so that the stoke outline paints outwards towards LEFT and TOP of Shape, rather than inside of the shape, over writing my text when I make the thinkness of the stroke too thick... I want the radius of my ellipse to stay constant, but the stroke to grow outwards with increased thinkness, and the LEFT, TOP placement of the shape to remain contant with the inner fill staying the same size and not getting covered up by stroke as it is increased in size.
I tried DropShadowEffect, but its kind of too blurry and not well defined enough...and looks kind of messy... really I just want a solid line going around the outside of the shape...
As you can see from attached picture above, I tried to put shadow around two the ellipses using this code below. the problem is that I want it to be a solid color around the outside like a scaletransform of another ellipse of a different color.
var e = new Ellipse();
DropShadowEffect effect = new DropShadowEffect();
effect.Color =Colors.Orange;
effect.Direction = 0;
effect.BlurRadius = 30;
effect.ShadowDepth = 4;
effect.Opacity=0;
e.Effect = effect;
t.Text = string.Format("abc");
t.Measure(new Size(gwin.XStep, gwin.YStep));
t.Arrange(new Rect(t.DesiredSize));
e.StrokeThickness = 2;
e.Stroke = Brushes.Black;
canvas.Children.Add(e);
canvas.Children.Add(t);
Another possible direction towards solving the problem:
<Ellipse RenderTransformOrigin="0.5,0.5">
<Ellipse.RenderTransform>
<TransformGroup>
<ScaleTransform/>
</TransformGroup>
</Ellipse.RenderTransform>
</Ellipse>
Convert to c# code and place one scaletransform ellipse centered inside another scaled transform ellipse of different colors... not sure how to set it up though.
Solution:
Based on suggestion below. I tried creating a grid, setting the width and height of the grid to the size of my ellipse, then adding two ellipses to the grid with different colors and one with a margin set to -10. and it works perfectly ... just need to place the larger ellipse with margin -10 behind the other ellipse when adding it to the grid...here's what it looks like now..
Solution is in here somewhere:
g = new Grid();
e = new Ellipse();
h = new Ellipse();
t = new TextBlock();
t.HorizontalAlignment = HorizontalAlignment.Center;
t.VerticalAlignment = VerticalAlignment.Center;
t.FontWeight = FontWeights.ExtraBold;
g.Children.Add(h);
g.Children.Add(e);
g.Children.Add(t);
gwin.canvas.Children.Add(g);
t.Text = String.Format("{0}.{1}", x, y);
g.Width = gwin.XStep;
g.Height = gwin.YStep;
Canvas.SetLeft (g, gwin.X1 + gwin.XStep*x*2);
Canvas.SetTop (g, gwin.Y1 + gwin.YStep*y*2);
e.StrokeThickness = 2;
e.Stroke = Brushes.Black;
h.Margin = new Thickness(-10);
You can use double ellipses inside a grid overlaying each other like this:
<Grid Width="100" Height="100">
<Ellipse Fill="Black" Margin="-10"/>
<Ellipse Fill="Red" />
</Grid>
The size of this compound is still 100x100 even though the first ellipse is bigger and rendered out of its boundaries.
You may also use a Path and then do this
I think there is something like border. Or you can draw one elipse and then a second one in smaller that has the background color.

WPF C# Drawing line by using coordinates of buttons

I have 2 buttons created in code behind ,I am trying to draw a line that connects them by getting the button coordinates, but it doesn't work the way that I wanted , I am new to this , am I doing this the right way?
I searched internet for line connecting 2 controls, but I just want a simple one that make use of coordinates to connect them .
Here are my codes :
Button btn1 = new Button();
btn1.Content = "Hello";
btn1.Width = 150;
btn1.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
wrapPanel1.Children.Add(btn1);
btn1.PreviewMouseDown += new MouseButtonEventHandler(btn1_MouseDown);
Button btn2 = new Button();
btn2.Content = "World";
btn2.Width = 150;
btn2.HorizontalAlignment = System.Windows.HorizontalAlignment.Right;
btn2.PreviewMouseDown += new MouseButtonEventHandler(btn1_MouseDown);
wrapPanel1.Children.Add(btn2);
private void ShowLocation(ContentControl element)
{
var location = element.PointToScreen(new Point(0, 0));
MessageBox.Show(string.Format(
"{2}'s location is ({0}, {1})",
location.X,
location.Y,
element.Content));
Line redLine = new Line();
redLine.X1 = location.X;
redLine.Y1 = location.Y;
redLine.X2 = 323;
redLine.Y2 = 167;
//Create a red Brush
SolidColorBrush redBrush = new SolidColorBrush();
redBrush.Color = Colors.Red;
//Set Line's width and color
redLine.StrokeThickness = 4;
redLine.Stroke = redBrush;
// Add line to the Grid.
wrapPanel1.Children.Add(redLine);
}
private void btn1_MouseDown(object sender, RoutedEventArgs e)
{
var element = sender as ContentControl;
if (element != null)
{
ShowLocation(element);
}
}
As you notice the X2 and Y2 coordinates I just random giving it a number but the X1 and Y1 is suppose to be drawn from the button but it is not.
The line is appearing somewhere else away from the button, but the coords I use are the coords of the button.
Also, I have to dynamically create many buttons from db, This is just testing out yet I am stuck here.
__EDIT____
trying out with 1 button , i realise when maximize and minimize , the coords are different , this is how it looks like , the button seems to increase its height everytime i click on it to generate the line .
i want the line to start from the end of the button width at the side , if its not possible , it will be good for the button to overlap the line but is that possible?
The main problem is that WPF mostly uses layout-based positioning (Grid, DockPanel, etc), instead of Windows Forms, which is coordinate-based. This means, that real location of left top element's corner depends from layout control being used and its current settings (and yes, this usually blows up your mind, if you are very new to WPF).
If you want to manage position of elements by coordinates in WPF, then you should use Canvas (you can easily translate this sample from XAML to C#):
<Canvas>
<Button Canvas.Left="10" Canvas.Top="10" Width="20" Height="20" Content="A"/>
<Button Canvas.Left="50" Canvas.Top="50" Width="20" Height="20" Content="B"/>
<Line Canvas.Left="30" Canvas.Top="30" X2="20" Y2="20" StrokeThickness="4" Stroke="Red"/>
</Canvas>

C# canvas going overpainted

I have a Canvas in my MainWindow and I draw a line there. When it draws over the width/height of my Canvas, the drawing continues in my MainWindow. Is there a mistake in my code or is that normal?
<Canvas x:Name="coordinateSystem" HorizontalAlignment="Right" Height="580" Margin="0,10,283,0" VerticalAlignment="Top" Width="1024" Cursor="Cross" UseLayoutRounding="False"/>
Here is my function I call everytime when I get a new coordinate for my line:
// xOld, yOld and t are static
// t represents the time
private void drawPoly(double value)
{
t++;
Point pOne = new Point(xOld, yOld);
Point pTwo = new Point(t, value);
GeometryGroup lineGroup = new GeometryGroup();
LineGeometry connectorGeometry = new LineGeometry();
connectorGeometry.StartPoint = pOne;
connectorGeometry.EndPoint = pTwo;
lineGroup.Children.Add(connectorGeometry);
System.Windows.Shapes.Path path = new System.Windows.Shapes.Path();
path.Data = lineGroup;
path.StrokeThickness = 1;
path.Stroke = path.Fill = Brushes.Red;
coordinateSystem.Children.Add(path);
xOld = t;
yOld = value;
}
thx
PS: Is there a way to save all drawn points? I want later resize my canvas (zoom out/zoom in) or if the time going to big move my painted line in my canvas and then I need to draw all points again.
Canvases do not clip child elements. If you want to stop the child elements from being drawn outside of the Canvas, you'll need to set ClipToBounds to true or set the Clip of the Canvas.

Categories

Resources