WPF - pass data from page A to page B - wpf

So I want to pass data when I clicked an Canvas. So I have this code;
Canvas event_canvas = new Canvas();
event_canvas.Background = new SolidColorBrush(Color.FromRgb(66, 70, 77));
event_canvas.Width = 250;
event_canvas.Height = 60;
event_canvas.Margin = new Thickness(40, 0, 0, 0);
event_canvas.HorizontalAlignment = HorizontalAlignment.Left;
event_canvas.VerticalAlignment = VerticalAlignment.Top;
event_canvas.Cursor = Cursors.Hand;
#endregion
#region Grid (event_grid)
Grid event_grid = new Grid();
event_grid.Width = 250;
event_grid.Height = 60;
#endregion
#region TextBlock (event_text)
TextBlock event_text = new TextBlock();
event_text.VerticalAlignment = VerticalAlignment.Center;
event_text.HorizontalAlignment = HorizontalAlignment.Center;
event_text.Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255));
event_text.Text = e.name;
#endregion
event_grid.Children.Add(event_text); // Add the textblock to the grid
event_canvas.Children.Add(event_grid); // Add the grid to the canvas
grid_events.Children.Add(event_canvas); // Add the canvas to the main grid.
// Click event registration
event_canvas.MouseLeftButtonDown += Event_canvas_MouseLeftButtonDown;
And then in the trigger;
private void Event_canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Page pg = new EventDetailPage();
// Replaces all the content!!!!!
this.Content = pg;
//throw new NotImplementedException();
}
I tried to add this;
var param = ((TextBlock)sender).Text;
Page pg = new EventDetailPage(param);
But that code doesn't work, it throws an error that I can't get a value.
How can I fix this issue?

Cast the sender argument to Canvas and then access the Grid through the Canvas' Children collecton and the TextBlock through the Grid's Children collecton:
private void Event_canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Canvas canvas = (Canvas)sender;
Grid event_grid = canvas.Children[0] as Grid;
TextBlock event_text = event_grid.Children[0] as TextBlock;
string text = event_text.Text;
...
}

Related

Draw line on run time WPF

I want to draw line on run time using mouse.I have tried in below way
private void Image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
FrameworkElement f = e.Source as FrameworkElement;
FrameworkElement pr = f.Parent as FrameworkElement;
Rect feRect = f.TransformToAncestor(pr).TransformBounds(
new Rect(0.0, 0.0, f.ActualWidth, f.ActualHeight));
Image image = sender as Image;
Point textLocation = e.GetPosition(image);
textLocation.Offset(-4, -4);
var Top = feRect.Height - textLocation.Y;
var Bottom = textLocation.Y - 1;
var Left = textLocation.X - 1;
var Right = feRect.Width-textLocation.X;
// Create an annotation where the mouse cursor is located.and add control using adorner layer
_currentAnnotations = ImageAnnotation.Create(
image,
textLocation,
feRect
);
}
private void Image_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Image image = sender as Image;
EndPosition = e.MouseDevice.GetPosition(image);
// Draw next line and...
l.X1 = StartPosition.X;
l.X2 = EndPosition.X;
l.Y1 = StartPosition.Y;
l.Y2 = EndPosition.Y;
l.Stroke = Brushes.Red;
l.StrokeThickness = 5;
StartPosition = EndPosition;
}
if(_currentAnnotations!=null && l!=null)
_currentAnnotations.Lines = l;
}
But it doesn't give the result as expected. the line that am getting is different from the mouse location. my output should be like a pen tool. 1.what's wrong with my way?
2. Is inkCanvas the only way to draw line in wpf?if yes why so?
3.
1.what's wrong with my way?
You could try to set the StartPosition property in the Image_MouseLeftButtonDown event handler:
private void Image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
FrameworkElement f = e.Source as FrameworkElement;
FrameworkElement pr = f.Parent as FrameworkElement;
Rect feRect = f.TransformToAncestor(pr).TransformBounds(
new Rect(0.0, 0.0, f.ActualWidth, f.ActualHeight));
Image image = sender as Image;
...
StartPosition = e.MouseDevice.GetPosition(image);
}
InkCanvas is the only built-in WPF control that receives and displays ink strokes. But you could for example add lines to a Canvas or perform any other kind of custom drawing action yourself.
Here is a basic sample that should give you the idea.
public partial class MainWindow : Window
{
public MainWindow ()
{
InitializeComponent();
}
Point EndPosition;
Point StartPosition;
private void canvas_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
FrameworkElement fe = sender as FrameworkElement;
EndPosition = e.MouseDevice.GetPosition(fe);
Line l = new Line();
l.X1 = StartPosition.X;
l.X2 = EndPosition.X;
l.Y1 = StartPosition.Y;
l.Y2 = EndPosition.Y;
l.Stroke = Brushes.Red;
l.StrokeThickness = 5;
StartPosition = EndPosition;
canvas.Children.Add(l);
}
}
private void canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
FrameworkElement fe = sender as FrameworkElement;
StartPosition = e.MouseDevice.GetPosition(fe);
}
}
<Canvas x:Name="canvas" Width="500" Height="500" Background="Yellow"
MouseLeftButtonDown="canvas_MouseLeftButtonDown" MouseMove="canvas_MouseMove" />

How to draw dropshadow effect in a geometry in WPF

I'm drawing the following Shape in a Canvas.
I would like to highlight it when it's selected by changing its color (the easy part) and drawing an small halo around it:
This is how I did using SASS: http://codepen.io/aaromnido/pen/zKvAwd/
How coud I draw in WPF? Remember that I'm drawing using the Shape's OnRender method.
Set some defaults in constructor.
One of these defaults is Shape.Effect, as it will be animated on MouseEnter event.
Construct VisualStates for Normal , and MouseEnter scenarios.
Change the VisualState of the element using VisualStateManager.GoToElementState() in MouseEnter and MouseLeave event handlers.
You can expose various properties using DPs for customization.
NewShape.cs
using System.Windows.Shapes;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows;
using System.Windows.Media.Effects;
namespace WpfStackOverflow.NewShape
{
public class CNewShape : Shape
{
public CNewShape()
{
// setting the defaults
this.Width = 40;
this.Height = 40;
this.Stroke = new SolidColorBrush() { Color = Colors.Red };
this.StrokeThickness = 5;
this.Effect = new DropShadowEffect() {
Color = Colors.Transparent,
BlurRadius = 1,
Direction = -150,
ShadowDepth = 1
};
// constructing the VisualStates
_constructVisualStates();
// event handlers
this.MouseEnter += CNewShape_MouseEnter;
this.MouseLeave += CNewShape_MouseLeave;
}
#region EventHandlers
void CNewShape_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
{
VisualStateManager.GoToElementState(this, "VSNormal", false);
}
void CNewShape_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
{
VisualStateManager.GoToElementState(this, "VSMouseEnter", false);
}
#endregion
#region Overrides
// This needs to be implemented as it is abstract in base class
GeometryGroup geo = new GeometryGroup();
protected override Geometry DefiningGeometry
{
get { return geo; }
}
protected override void OnRender(System.Windows.Media.DrawingContext drawingContext)
{
Pen pen = new Pen(this.Stroke, StrokeThickness);
drawingContext.DrawEllipse(Brushes.Transparent, pen, new Point(Width/2, Height/2), 40, 40);
drawingContext.DrawEllipse(Stroke, null, new Point(Width / 2, Height / 2), 30, 30);
base.OnRender(drawingContext);
}
#endregion
#region Helpers
private void _constructVisualStates()
{
VisualStateGroup vsg1 = new VisualStateGroup();
#region VSNormal (Normal Visual State)
VisualState stateVSNormal = new VisualState() { Name = "VSNormal" };
Storyboard sbVSNormal = new Storyboard();
ObjectAnimationUsingKeyFrames oa = new ObjectAnimationUsingKeyFrames();
Storyboard.SetTargetProperty(oa, new PropertyPath("Effect"));
DiscreteObjectKeyFrame dokf = new DiscreteObjectKeyFrame(null);
oa.KeyFrames.Add(dokf);
sbVSNormal.Children.Add(oa);
stateVSNormal.Storyboard = sbVSNormal;
vsg1.States.Add(stateVSNormal);
#endregion
#region VSMouseEnter (MouseEnter Visual State)
VisualState stateVSMouseEnter = new VisualState() { Name = "VSMouseEnter" };
Storyboard sbVSMouseEnter = new Storyboard();
ColorAnimation caStrokeColor = new ColorAnimation();
caStrokeColor.To = (Color)ColorConverter.ConvertFromString("#FF24BCDE");
Storyboard.SetTargetProperty(caStrokeColor, new PropertyPath("(Shape.Stroke).(SolidColorBrush.Color)"));
sbVSMouseEnter.Children.Add(caStrokeColor);
ColorAnimation caEffectColor = new ColorAnimation();
caEffectColor.To = (Color)ColorConverter.ConvertFromString("#FFA4E1F3");
Storyboard.SetTargetProperty(caEffectColor, new PropertyPath("(Shape.Effect).(Color)"));
sbVSMouseEnter.Children.Add(caEffectColor);
DoubleAnimation daBlurRadius = new DoubleAnimation();
daBlurRadius.To = 10;
Storyboard.SetTargetProperty(daBlurRadius, new PropertyPath("(Shape.Effect).(BlurRadius)"));
sbVSMouseEnter.Children.Add(daBlurRadius);
DoubleAnimation daDirection = new DoubleAnimation();
daDirection.To = -190;
Storyboard.SetTargetProperty(daDirection, new PropertyPath("(Shape.Effect).(Direction)"));
sbVSMouseEnter.Children.Add(daDirection);
stateVSMouseEnter.Storyboard = sbVSMouseEnter;
vsg1.States.Add(stateVSMouseEnter);
#endregion
VisualStateManager.GetVisualStateGroups(this).Add(vsg1);
}
#endregion
}
}
Usage
<local:CNewShape Canvas.Left="70" Canvas.Top="52" Stroke="#FF374095" StrokeThickness="10" Width="100" Height="100" />
Output
Quality of the image is bad. On screen actual output looks good.
Whatever your trigger is that your control enters the Highlighted state, in that trigger just set the Effect property. For my test the "trigger" is a property:
public static readonly DependencyProperty ShowShadowProperty =
DependencyProperty.Register ("ShowShadow", typeof (bool), typeof (TestShape), new PropertyMetadata (false, ShowShadowChanged));
public bool ShowShadow
{
get { return (bool)GetValue (ShowShadowProperty); }
set { SetValue (ShowShadowProperty, value); }
}
private static void ShowShadowChanged (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((TestShape)d).OnShowShadow ();
}
private void OnShowShadow ()
{
if (ShowShadow)
{
Effect = new DropShadowEffect { Direction = 0, ShadowDepth = 20, BlurRadius = 33, Opacity = 1, Color = Colors.Black};
}
else
{
Effect = null;
}
}
Which means you don't need to do anything in OnRender.

Finding controls in Windows Forms C# .NET?

Using Windows Forms, two link labels are created dynamically. When the user clicks on anyone of links labels, one dynamic form is created. In that form I created one data grid, a text box and a button placed dynamically (in that dynamic form). Now I want to access the dynamic data grid in the dynamic button click event. How can I do that?
private void Users_Load(object sender, EventArgs e)
{
da = new SqlDataAdapter("Usp_Get_Employees", con);
ds = new DataSet();
da.Fill(ds);
if (ds.Tables[0].Rows.Count > 0)
{
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
string somecode = i.ToString() + ds.Tables[0].Rows[i]["eid"].ToString();
LinkLabel lbluser = new LinkLabel();
lbluser.Name = ds.Tables[0].Rows[i]["eid"].ToString();
lbluser.Text = ds.Tables[0].Rows[i]["ename"].ToString();
lbluser.Location = new System.Drawing.Point(40, i * 40);
lbluser.Size = new System.Drawing.Size(50, 30);
Controls.Add(lbluser);
lbluser.Click += new EventHandler(lbluser_Click);
}
}
}
void lbluser_Click(object sender, EventArgs e)
{
LinkLabel lnkClis = (LinkLabel)sender;
Form frm = new Form();
frm.Name = lnkClis.Name;
frm.Text = lnkClis.Text;
frm.Show();
DataGrid dtgrd = new DataGrid();
dtgrd.Location = new System.Drawing.Point(10, 1 * 40);
dtgrd.Name = lnkClis.Name;
names = lnkClis.Name;
TextBox tx = new TextBox();
tx.Location = new System.Drawing.Point(10, 5 * 40);
tx.Size = new Size(80, 30);
tx.Multiline = true;
tx.LostFocus += new EventHandler(tx_LostFocus);
Button btn = new Button();
btn.Location = new System.Drawing.Point(10, 7 * 40);
btn.Size = new System.Drawing.Size(50, 30);
btn.Name = lnkClis.Name;
btn.Click += new EventHandler(btn_Click);
frm.Controls.Add(dtgrd);
frm.Controls.Add(tx);
frm.Controls.Add(btn);
}
// Now I am trying to access the data grid in the btn_click event
void btn_Click(object sender, EventArgs e)
{
Button btsave = (Button)sender;
string eid = btsave.Name;
object grd = btsave.Parent.Controls.Find("dtgrd", true).FirstOrDefault();
((DataGrid)grd).DataSource = ds.Tables[0];
}
Now I am getting an error object set of instances of an object at:
((DataGrid)grd).DataSource = ds.Tables[0];
The exception message you have written:
Now I am getting an error object set of instances of an object at
makes no sense, but it looks like
Object reference not set to an instance of an object
If this is the case, I think the error lays in Find method call. According to documentation:
Searches for controls by their Name property and builds an array of all the controls that match.
In your button click handler you assume that grid is called dtgrd, but while you create a grid you name it like this:
dtgrd.Name = lnkClis.Name;
it will suffice if you change this line to:
dtgrd.Name = "dtgrd";
Having said that, you should consider using an anonymous method for the button click handler. It will eliminate need for calling the Find method in the first place.
void lbluser_Click(object sender, EventArgs e)
{
//...
DataGrid dtgrd = new DataGrid();
//...
Button btn = new Button();
//...
btn.Click += (sender,args)=> dtgrd.DataSource = ds.Tables[0];
Try the following code
public Form1()
{
Form f1 = new Form();
f1.Text = "New Form";
TextBox t1 = new TextBox();
t1.Top = 0;
t1.Name = "t1";
t1.Visible = true;
f1.Controls.Add(t1);
Button b1 = new Button();
b1.Top = 30;
b1.Name = "b1";
b1.Text = "Click";
b1.Click += b1_Click;
f1.Controls.Add(b1);
f1.Show();
}
public void b1_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
object txt = btn.Parent.Controls.Find("t1", false).First();
((TextBox)txt).Text = "Hi, you have clicked me.";
}
I modified Nitesh's code a bit. Just capture the textbox in the click handler using a lambda:
public Form1()
{
Form f1 = new Form();
f1.Text = "New Form";
TextBox t1 = new TextBox();
t1.Top = 0;
t1.Name = "t1";
t1.Visible = true;
f1.Controls.Add(t1);
Button b1 = new Button();
b1.Top = 30;
b1.Name = "b1";
b1.Text = "Click";
b1.Click += (sender, args) => MessageBox.Show("The text is: " + t1.Text);
f1.Controls.Add(b1);
f1.Show();
}
The error you are getting is from the statement (as the grd object is null):
((DataGrid)grd).DataSource = ds.Tables[0];
Since you are trying to catch hold of a dynamic control, it's good have a proper null checks, type checks, and error handling. Something like this:
if(grd != null && grd is DataGrid)
((DataGrid)grd).DataSource = ds.Tables[0];

Print Grid which generated dynamically in wpf

i want to print a grid which is generated dynamically.
Means, in the click event of the Print Button, i m generating a grid and then i want to print that grid.
here is my code,
private void btnPrint_Click(object sender, RoutedEventArgs e)
{
PrintDialog Objprint = new System.Windows.Controls.PrintDialog();
if (Objprint.ShowDialog() == true)
{
System.Printing.PrintCapabilities capabilities = Objprint.PrintQueue.GetPrintCapabilities(Objprint.PrintTicket);
double scale = Math.Min(capabilities.PageImageableArea.ExtentWidth / this.ActualWidth, capabilities.PageImageableArea.ExtentHeight / this.ActualHeight);
#region "Make a grid For Printing"
Grid objgrid = new Grid();
objgrid.Name = "GridForPrinting";
objgrid.Width = 1000;
objgrid.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
objgrid.VerticalAlignment = System.Windows.VerticalAlignment.Top;
objgrid.RowDefinitions.Add(new RowDefinition());
TextBlock objtext = new TextBlock();
objtext.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
objtext.VerticalAlignment = System.Windows.VerticalAlignment.Center;
objtext.Text = "SUPERIOR COURT OF CALIF COUNTY OF SAN BERNARDINO";
Grid.SetRow(objtext, 0);
objgrid.Children.Add(objtext);
#endregion
Objprint.PrintVisual(objgrid, "Case Summary");
}
}
this code give me blank page to print.
how can i do that?
here i get answer,
from the below code i get what i want to do...
void PrintOnClick(object sender, RoutedEventArgs args)
{
PrintDialog dlg = new PrintDialog();
if ((bool)dlg.ShowDialog().GetValueOrDefault())
{
// Create Grid panel.
Grid grid = new Grid();
// Define 5 auto-sized rows and columns.
for (int i = 0; i < 5; i++)
{
ColumnDefinition coldef = new ColumnDefinition();
coldef.Width = GridLength.Auto;
grid.ColumnDefinitions.Add(coldef);
RowDefinition rowdef = new RowDefinition();
rowdef.Height = GridLength.Auto;
grid.RowDefinitions.Add(rowdef);
}
// Give the Grid a gradient brush.
grid.Background =
new LinearGradientBrush(Colors.Black, Colors.White,
new Point(0, 0), new Point(1, 1));
// Every program needs some randomness.
Random rand = new Random();
// Fill the Grid with 25 buttons.
for (int i = 0; i < 25; i++)
{
Button btn = new Button();
btn.FontSize = 12 + rand.Next(8);
btn.Content = "Button No. " + (i + 1);
btn.HorizontalAlignment = HorizontalAlignment.Center;
btn.VerticalAlignment = VerticalAlignment.Center;
btn.Margin = new Thickness(6);
grid.Children.Add(btn);
Grid.SetRow(btn, i % 5);
Grid.SetColumn(btn, i / 5);
}
// Size the Grid.
grid.Measure(new Size(Double.PositiveInfinity,
Double.PositiveInfinity));
Size sizeGrid = grid.DesiredSize;
// Determine point for centering Grid on page.
Point ptGrid =
new Point((dlg.PrintableAreaWidth - sizeGrid.Width) / 2,
(dlg.PrintableAreaHeight - sizeGrid.Height) / 2);
// Layout pass.
grid.Arrange(new Rect(ptGrid, sizeGrid));
// Now print it.
dlg.PrintVisual(grid, Title);
}
}
The PrintVisual print a Visual object. That means, by using the PrintVisual method, we can print any control, container, Window or user control that is in the visualtree.You cannot print a control that is not in the visualtree

Problem adding Viewport2DVisual3D from Code

I'm trying to add a Viewport2DVisual3D to a Viewport3D in code, but the visual isn't showing up. Any help understanding why not would be appreciated. The following is the code for the main window.
Is it sufficient to just add the Viewport2DVisual3D to the children of the Viewport3D in order for it to be rendered?
public partial class Window1 : System.Windows.Window
{
public Window1()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(temp);
}
public void temp(object sender, RoutedEventArgs e)
{
Viewport2DVisual3D test = new Viewport2DVisual3D();
MeshGeometry3D testGeometry = new MeshGeometry3D();
Vector3D CameraLookDirection = Main_Target_CameraOR20.LookDirection;
// Calculate the Positions based on the Camera
Point3DCollection myPoint3DCollection = new Point3DCollection();
myPoint3DCollection.Add(new Point3D(-1, 1, 0));
myPoint3DCollection.Add(new Point3D(-1, -1, 0));
myPoint3DCollection.Add(new Point3D(1, -1, 0));
myPoint3DCollection.Add(new Point3D(1, 1, 0));
testGeometry.Positions = myPoint3DCollection;
PointCollection myPointCollection = new PointCollection();
myPointCollection.Add(new Point(0, 0));
myPointCollection.Add(new Point(0, 1));
myPointCollection.Add(new Point(1, 1));
myPointCollection.Add(new Point(1, 0));
testGeometry.TextureCoordinates = myPointCollection;
Int32Collection triangleIndicesCollection = new Int32Collection();
triangleIndicesCollection.Add(0);
triangleIndicesCollection.Add(1);
triangleIndicesCollection.Add(2);
triangleIndicesCollection.Add(2);
triangleIndicesCollection.Add(3);
triangleIndicesCollection.Add(0);
testGeometry.TriangleIndices = triangleIndicesCollection;
DiffuseMaterial myDiffuseMaterial = new DiffuseMaterial(Brushes.White);
Viewport2DVisual3D.SetIsVisualHostMaterial(myDiffuseMaterial, true);
Transform3DGroup myTransform3DGroup = new Transform3DGroup();
ScaleTransform3D myScaleTransform3D = new ScaleTransform3D();
myScaleTransform3D.ScaleX = 2;
myScaleTransform3D.ScaleY = 2;
myScaleTransform3D.ScaleZ = 2;
TranslateTransform3D myTranslateTransform3D = new TranslateTransform3D();
myTranslateTransform3D.OffsetX = -27;
myTranslateTransform3D.OffsetY = 13;
myTranslateTransform3D.OffsetZ = 6;
RotateTransform3D rotateTransform = new RotateTransform3D()
{
Rotation = new AxisAngleRotation3D
{
Angle = -50,
Axis = new Vector3D(0, 1, 0)
}
};
myTransform3DGroup.Children.Add(myTranslateTransform3D);
myTransform3DGroup.Children.Add(myScaleTransform3D);
myTransform3DGroup.Children.Add(rotateTransform);
test.Transform = myTransform3DGroup;
Button myButton = new Button();
myButton.Content = "Test Button";
test.Material = myDiffuseMaterial;
test.Geometry = testGeometry;
test.Visual = myButton;
ZAM3DViewport3D.Children.Add(test);
}
}
It turns out that the problem was the Offset value. So, it is sufficient to add the child to the Viewport3D to have it render. Cheers

Resources