Can WPF window contain a child ? - c#

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);

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("..."));

Silverlight grid not filling entire space

I have content object in wcf.
I try store in content property grid but it not fill the entire length.
Function return grid:
private Grid ChangeContentObject()
{
Grid g = new Grid();
g.Background = new SolidColorBrush(Colors.Red);
g.HorizontalAlignment = HorizontalAlignment.Stretch;
g.VerticalAlignment = VerticalAlignment.Stretch;
ColumnDefinition columnDefinitionForPath = new ColumnDefinition();
columnDefinitionForPath.Width = new GridLength(4,GridUnitType.Star);
ColumnDefinition columnDefinitionForEmpty = new ColumnDefinition();
columnDefinitionForEmpty.Width = new GridLength(6, GridUnitType.Star);
g.ColumnDefinitions.Add(columnDefinitionForPath);
g.ColumnDefinitions.Add(columnDefinitionForEmpty);
WindowsShapes.Path p = new WindowsShapes.Path();
p.Stroke = new SolidColorBrush(Colors.Brown);
p.StrokeThickness = 2;
p.HorizontalAlignment = HorizontalAlignment.Stretch;
var b = new Binding
{
Source = "M50,0 L0,0 L0,50 L50,50"
};
BindingOperations.SetBinding(p, WindowsShapes.Path.DataProperty, b);
p.Stretch = Stretch.Fill;
g.Children.Add(p);
Grid.SetColumn(p, 0);
return g;
}
Code for set content:
objectVisual.Content = ChangeContentObject();
objectVisual property:
objectVisual.VerticalAlignment = Stretch
objectVisual.VerticalAlignment
objectVisual.Width = 100
objectVisual.Height = 50
I get next result:
Why grid does not fill the entire length?
Your Grid has 2 columns. The second column is empty, and therefore collapsed, so you can't see it. Binding something to it solves the "problem". Also, modified your Path data for this demo, because the one you had is no good. Take a look:
private Grid ChangeContentObject()
{
Grid g = new Grid();
g.Background = new SolidColorBrush(Colors.Red);
g.HorizontalAlignment = HorizontalAlignment.Stretch;
g.VerticalAlignment = VerticalAlignment.Stretch;
// add grid line to show columns border
g.ShowGridLines = true;
ColumnDefinition columnDefinitionForPath = new ColumnDefinition();
columnDefinitionForPath.Width = new GridLength(4, GridUnitType.Star);
ColumnDefinition columnDefinitionForEmpty = new ColumnDefinition();
columnDefinitionForEmpty.Width = new GridLength(6, GridUnitType.Star);
g.ColumnDefinitions.Add(columnDefinitionForPath);
g.ColumnDefinitions.Add(columnDefinitionForEmpty);
var p1 = new Path();
p1.Stroke = new SolidColorBrush(Colors.Brown);
p1.StrokeThickness = 2;
p1.Stretch = Stretch.Fill;
p1.HorizontalAlignment = HorizontalAlignment.Stretch;
var b1 = new Binding
{
// modified path data
Source = "M 10,100 C 10,300 300,-200 300,100"
};
BindingOperations.SetBinding(p1, Path.DataProperty, b1);
var p2 = new Path();
p2.Stroke = new SolidColorBrush(Colors.Brown);
p2.StrokeThickness = 2;
p2.Stretch = Stretch.Fill;
p2.HorizontalAlignment = HorizontalAlignment.Stretch;
var b2 = new Binding
{
// modified path data
Source = "M 100,10 C 100,30 -200,100 100,300"
};
BindingOperations.SetBinding(p2, Path.DataProperty, b2);
g.Children.Add(p1);
g.Children.Add(p2);
Grid.SetColumn(p1, 0);
Grid.SetColumn(p2, 1);
return g;
}
Update:
Normally, a Grid would stretch and expand on its own, no need at all to "fill it with empty space". The problem here is caused by the fact that you're placing your Grid enclosed within objectVisual, which apparently is a ContentControl (you didn't make it clear in your post). So, instead you should make objectVisual a type derived from a Panel, like, let's say, another Grid.
And then, replace this:
objectVisual.Content = ChangeContentObject();
with this:
objectVisual.Children.Add(ChangeContentObject());
And you'll get what you want:
Update 2:
Well, your pastebin code is slightly different from your original code, and although that would work too, you misunderstood what I said about the Grid. You don't need your var gridChild, you can keep the second column empty, like in your original question. Notice I commented it out. So, in order to clarify, I am posting full MCVE sample code below. The result looks just like the second image I posted above previously.
UserControl CS:
public partial class SilverlightControl3 : UserControl
{
public SilverlightControl3()
{
InitializeComponent();
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
objectVisual.Children.Add(ChangeContentObject());
}
private Grid ChangeContentObject()
{
Grid g = new Grid();
g.Background = new SolidColorBrush(Colors.Red);
g.HorizontalAlignment = HorizontalAlignment.Stretch;
g.VerticalAlignment = VerticalAlignment.Stretch;
// add grid line to show columns border
g.ShowGridLines = true;
ColumnDefinition columnDefinitionForPath = new ColumnDefinition();
columnDefinitionForPath.Width = new GridLength(4, GridUnitType.Star);
ColumnDefinition columnDefinitionForEmpty = new ColumnDefinition();
columnDefinitionForEmpty.Width = new GridLength(6, GridUnitType.Star);
g.ColumnDefinitions.Add(columnDefinitionForPath);
g.ColumnDefinitions.Add(columnDefinitionForEmpty);
var p1 = new Path();
p1.Stroke = new SolidColorBrush(Colors.Blue);
p1.StrokeThickness = 2;
p1.Stretch = Stretch.Fill;
p1.HorizontalAlignment = HorizontalAlignment.Stretch;
g.Children.Add(p1);
Grid.SetColumn(p1, 0);
var b1 = new Binding
{
Source = "M 10,100 C 10,300 300,-200 300,100"
};
BindingOperations.SetBinding(p1, Path.DataProperty, b1);
// you dont necessarily need this here, you can keep it empty like before
/*
var gridChild = new Grid();
g.Children.Add(gridChild);
Grid.SetColumn(gridChild, 1);
*/
return g;
}
}
UserControl XAML:
<UserControl x:Class="SilverlightApplication4.SilverlightControl3"
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="300" d:DesignWidth="400" Loaded="UserControl_Loaded">
<Grid x:Name="LayoutRoot" Background="White">
<Grid x:Name="objectVisual" />
</Grid>
</UserControl>
MainWindow:
<UserControl x:Class="SilverlightApplication4.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"
xmlns:local="clr-namespace:SilverlightApplication4"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot">
<local:SilverlightControl3 />
</Grid>
</UserControl>

WPF dynamic Textbox shows in different positions

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"/>

Display data dynamically in textBlock

I just want to display data dynamically,so i used the C# code,
TextBlock[] Cp = new TextBlock[ContactPersons.Count];
int i=0;
foreach(var item in ContactPersons)
{
Cp[i] = new TextBlock();
Cp[i].Margin = new Thickness(0,y_coordinateStart ,0,0);
Cp[i].Foreground = new SolidColorBrush(Colors.Green);
Cp[i].Visibility = Visibility.Visible;
Cp[i].Height = 30;
Cp[i].Width = 300;
y_coordinateStart += 35;
Cp[i].Text = item.firsName;
i++;
}
But nothing appears in my page.
What could be the problem??
You need to add them to the visual tree somehow... For instance
In your XAML:
<Window x:Class="MyClass"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Width="525"
Height="350">
<StackPanel x:Name="MainPanel" />
</Window>
In your code:
foreach(var item in ContactPersons)
{
TextBlock tb = new TextBlock();
tb.Margin = new Thickness(0,y_coordinateStart ,0,0);
tb.Foreground = new SolidColorBrush(Colors.Green);
tb.Visibility = Visibility.Visible;
tb.Height = 30;
tb.Width = 300;
y_coordinateStart += 35;
tb.Text = item.firsName;
MainPanel.Children.Add(tb);
}

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);
}

Categories