What I am looking for is for the user to
1. click on the canvas
2. a new label show up and the user can enter text.
3. When the user clicks elsewhere or hit enter the labels is finished editing.
This is what I have so far...
private void DrawingCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) {
var canvas = (Canvas)sender;
var point = e.GetPosition(canvas);
Label lbl = new Label();
lbl.Content = "start typing";
//lbl.Left = location.X;
//lbl.Top = location.Y;
//lbl.Focus = Boolean.TrueString;
canvas.Children.Add(lbl);
}
Any help would be greatly appreciated, thanks!
Try like this
<Window x:Class="WpfApplication2.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">
<Canvas x:Name="cnvs" PreviewMouseLeftButtonUp="cnvs_MouseLeftButtonUp" Background="Transparent"></Canvas>
private void cnvs_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var canvas = (Canvas)sender;
var point = e.GetPosition(canvas);
TextBox txtBox = new TextBox() {Width=80,AcceptsReturn=false };
canvas.Children.Add(txtBox);
Canvas.SetLeft(txtBox, point.X);
Canvas.SetTop(txtBox, point.Y);
txtBox.Focus();
}
I hope this will help.
UPDaTE:
var canvas = (Canvas)sender;
var point = e.GetPosition(canvas);
TextBox txtBox = new TextBox() {AcceptsReturn=false ,BorderThickness=new Thickness(0)};
Binding b = new Binding("Text") { RelativeSource = new RelativeSource(RelativeSourceMode.Self) };
txtBox.SetBinding(TextBox.WidthProperty, b);
canvas.Children.Add(txtBox);
Canvas.SetLeft(txtBox, point.X);
Canvas.SetTop(txtBox, point.Y);
txtBox.Focus();
Try setting the textbox width to Double.NaN. This will give you an "Auto" width. To get rid of the border, set the textbox's borderthickness to 0. See below:
private void cnvs_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var canvas = (Canvas)sender;
var point = e.GetPosition(canvas);
var txtBox = new TextBox() { Width=Double.NaN, AcceptsReturn=false }; // auto width
txtBox.BorderThickness = new Thickness(0); // no border
canvas.Children.Add(txtBox);
Canvas.SetLeft(txtBox, point.X);
Canvas.SetTop(txtBox, point.Y);
txtBox.Focus();
}
Related
I am creating some shapes from code behind dynamically and adding them to a Grid and further add the Grid to Canvas.
So when I double click on a shape I should be able to add some text which works fine. Now lets say I have two shapes on the Canvas and when I try to draw a line between these shapes for some reason the first shape gets pulled away to the bottom and the line starts from the middle of first shape.
I want the shape not to change the position and the line should start from the bottom of first shape. Please see the image for my problem.
Please help with your thoughts. Here is my code. Also I tried numerous posts eg: Getting the top left coordinates of a WPF UIElement.
But none of them seem to help.
private void CvsSurface_OnDrop(object sender, DragEventArgs e) //In this event I am creating a shape dynamically and adding to a grid which is then added to a canvas.
{
Shape result = null;
Object droppedData = e.Data; //This part is not important
/*Translate Drop Point in reference to Stack Panel*/
Point dropPoint = e.GetPosition(this.cvsSurface);
//Console.WriteLine(dropPoint);
//Label lbl = new Label();
//lbl.Content = draggedItem.Content;
UIElement element = draggedItem.Content as UIElement;
Shape s = element as Shape;
if (s is Ellipse)
{
Ellipse ellipse = new Ellipse()
{
Height = s.Height,
Width = s.Width,
Fill = s.Fill
};
result = ellipse;
}
else if (s is Rectangle)
{
Rectangle rectangle = new Rectangle()
{
Height = s.Height,
Width = s.Width,
Fill = s.Fill
};
result = rectangle;
}
Grid sp = new Grid();
sp.Children.Add(result);
sp.MouseLeftButtonDown += Sp_MouseLeftButtonDown;
sp.MouseLeftButtonUp += Sp_MouseLeftButtonUp;
//sp.PreviewMouseLeftButtonUp += Sp_PreviewMouseLeftButtonUp;
//sp.MouseLeftButtonUp += Sp_MouseLeftButtonUp;
cvsSurface.Children.Add(sp);
Canvas.SetLeft(sp, dropPoint.X);
Canvas.SetTop(sp, dropPoint.Y);
}
private void Sp_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) // The purpose of this event lets say when some one clicks on a shape and drags the mouse to the other shape and when mouse up I want to draw a line between the shapes.
{
bool mouserelease = System.Windows.Input.Mouse.LeftButton == MouseButtonState.Pressed;
if (!mouserelease)
{
x2 = e.GetPosition(stackpanel).X;
y2 = e.GetPosition(stackpanel).Y;
Line l = new Line();
l.X1 = x1;
l.Y1 = y1;
l.X2 = x2;
l.Y2 = y2;
l.Margin = new Thickness(0, 19, 0, 0);
l.Stroke = new SolidColorBrush(Colors.Black);
l.StrokeThickness = 2;
stackpanel.Children.Add(l);
}
}
private void Sp_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) //This method lets say if user clicks twice then he wants to add some text or if he single clicks then I am assuming he is trying to a drag and draw a line
{
stackpanel = sender as Grid; //Sorry, the stackpanel is a global variable name of type Grid. Its actually Grid stackpanel;
if (e.ClickCount == 2)
{
dialog = new UserDialog()
{
DataContext = this,
Height = 180,
Width = 400,
MaxHeight = 180,
MaxWidth = 400
};
dialog.ShowDialog();
}
else
{
x1 = e.GetPosition(stackpanel).X + 18;
y1 = e.GetPosition(stackpanel).Y + 18;
//x1 = GetPosition(stackpanel, cvsSurface).X;
//y1 = GetPosition(stackpanel, cvsSurface).Y;
}
}
I have this code, to add a new child:
private void Menu1_Click(object sender, RoutedEventArgs e)
{
Point centerPoint = new Point((Container.ActualWidth / 2) - (500/2), (Container.ActualHeight / 2) - (400 / 2));
MdiChild newForm = new MdiChild();
newForm.Title = "My Form";
newForm.Content = new MyForm1();
newForm.Width = 500;
newForm.Height = 400;
newForm.Resizable = false;
newForm.MaximizeBox = false;
newForm.Position = centerPoint;
Container.Children.Add(newForm);
}
This code is for the view:
<Window x:Class="WpfApplication1.MainWindow"
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:WpfApplication1"
mc:Ignorable="d"
xmlns:mdi="clr-namespace:WPF.MDI;assembly=WPF.MDI"
Title="WPF.MDI Example" Height="362" Width="684" WindowState="Maximized">
<DockPanel>
<mdi:MdiContainer Name="Container" Background="#FF474040" >
<mdi:MdiContainer.Menu>
<Menu DockPanel.Dock="Top" Width="677">
<MenuItem Header="Menu1" click="Menu1_Click">
</mdi:MdiContainer.Menu>
</mdi:MdiContainer>
</DockPanel>
How can I center MDI child Form?
It always opens in the upper left side
I don't find the solution yet,
Thanks.
I also tried to put this code, in the code behind form child, but it doesn't works:
public partial class MyForm1: UserControl
{
BalanceEntities db = new BalanceEntities();
public MyForm1()
{
InitializeComponent();
this.HorizontalAlignment = HorizontalAlignment.Center;
this.VerticalAlignment = VerticalAlignment.Center;
}
}
You should use WindowStartupLocation property of the Window like this:
private void Menu1_Click(object sender, RoutedEventArgs e)
{
Point centerPoint = new Point((Container.ActualWidth / 2) - (500/2), (Container.ActualHeight / 2) - (400 / 2));
MdiChild newForm = new MdiChild();
newForm .Title = "My Form";
//The code omitted for the brevity
newForm.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen;
Container.Children.Add(newForm);
}
OR:
this.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen;
Thanks for James Thorpe, I solve my problem at this way:
private void Menu1_Click(object sender, RoutedEventArgs e)
{
MdiChild newForm = new MdiChild();
newForm.Title = "My Form";
newForm.Content = new MyForm1();
newForm.Width = 500;
newForm.Height = 400;
newForm.Resizable = false;
newForm.MaximizeBox = false;
Container.Children.Add(newForm);
// And then I add the position:
Point centerPoint = new Point((Container.ActualWidth / 2) - (newForm.Width / 2), (Container.ActualHeight / 2) - (newForm.Height / 2));
newForm.Position = centerPoint;
}
Thanks for the help.
Do the following , it worked for me
newForm.StartPosition = FormStartPosition.CenterScreen;
I have a pdfViewer with an expander wrapped around it. I am trying to set the minimum height of content control inside expander when collapsed to 250 and when expanded set the height to the page height.
so even if the user collapses the expander he can see a part of the document. There is no property to set the height of content control and the expander's height property as set in code below is not working.
Is there any way of achieving this?
private void exPDF_Expanded(object sender, RoutedEventArgs e)
{
if (PDFCaption != null)
{
PDFCaption.Text = "Click to hide PDF.";
pdfViewer.Height = this.ActualHeight;
exPDF.Height = this.ActualHeight;
var rowIndex = Grid.GetRow(sender as Expander);
var Row = LayoutRoot.RowDefinitions[rowIndex];
Row.Height = GridLength.Auto;
}
}
private void exPDF_Collapsed(object sender, RoutedEventArgs e)
{
if (PDFCaption != null)
{
PDFCaption.Text = "Click to show PDF.";
pdfViewer.Height = 250;
exPDF.Height = 250;
var rowIndex = Grid.GetRow(sender as Expander);
var Row = LayoutRoot.RowDefinitions[rowIndex];
Row.Height = GridLength.Auto;
}
}
From code behind I can set some generic things to my groupbox and stackpanel but I cant find anything on how to highlight a stack panel from code behind.
GroupBox groupbox = new GroupBox();
groupbox.Header = String.Format(node.Element("StudentID").Value);
groupbox.Width = 100;
groupbox.Height = 100;
groupbox.Margin = new Thickness(1);
TextBlock textBlock = new TextBlock();
textBlock.Text = String.Format(node.Element("FirstName").Value + " " + (node.Element("LastName").Value));
textBlock.TextAlignment = TextAlignment.Center;
TextBlock textBlock1 = new TextBlock();
textBlock1.Text = (DateTime.Parse(node.Element("TimeAdded").Value)).ToString("d");
String.Format("{0:d/M/yyyy}", DateTime.Parse(node.Element("TimeAdded").Value));
textBlock1.TextAlignment = TextAlignment.Center;
textBlock1.VerticalAlignment = VerticalAlignment.Bottom;
StackPanel stackPanel = new StackPanel();
stackPanel.Children.Add(groupbox);
stackPanel.Children.Add(textBlock);
stackPanel.Children.Add(textBlock1);
stackPanel.Margin = new Thickness(5);
I wish to on mouse over create a highlight of a ligher grey, also this code belongs to a customcontrol.
Add handlers for the MouseEnter and MouseLeave events:
public MainWindow()
{
InitializeComponent();
StackPanel stackpanel = new StackPanel();
stackpanel.MouseEnter += new MouseEventHandler(stackpanel_MouseEnter);
stackpanel.MouseLeave += new MouseEventHandler(stackpanel_MouseLeave);
}
void stackpanel_MouseLeave(object sender, MouseEventArgs e)
{
StackPanel stackpanel = (StackPanel)sender;
stackpanel.Background = Brushes.Transparent;
}
void stackpanel_MouseEnter(object sender, MouseEventArgs e)
{
StackPanel stackpanel = (StackPanel)sender;
stackpanel.Background = Brushes.LightGray;
}
I was able to make my silverlight Bing map accepts Mousclicks and converts them to Pushpins in C#. Now I want to show a text next to the PushPin as a description that appears when the mouse goes over the pin , I have no clue how to do that. What are the methods that enable me to do this thing?
This is the C# code :
public partial class MainPage : UserControl
{
private MapLayer m_PushpinLayer;
public MainPage()
{
InitializeComponent();
base.Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
base.Loaded -= OnLoaded;
m_PushpinLayer = new MapLayer();
x_Map.Children.Add(m_PushpinLayer);
x_Map.MouseClick += OnMouseClick;
}
private void AddPushpin(double latitude, double longitude)
{
Pushpin pushpin = new Pushpin();
pushpin.MouseEnter += OnMouseEnter;
pushpin.MouseLeave += OnMouseLeave;
m_PushpinLayer.AddChild(pushpin, new Location(latitude, longitude), PositionOrigin.BottomCenter);
}
private void OnMouseClick(object sender, MapMouseEventArgs e)
{
Point clickLocation = e.ViewportPoint;
Location location = x_Map.ViewportPointToLocation(clickLocation);
AddPushpin(location.Latitude, location.Longitude);
}
private void OnMouseLeave(object sender, MouseEventArgs e)
{
Pushpin pushpin = sender as Pushpin;
// remove the pushpin transform when mouse leaves
pushpin.RenderTransform = null;
}
private void OnMouseEnter(object sender, MouseEventArgs e)
{
Pushpin pushpin = sender as Pushpin;
// scaling will shrink (less than 1) or enlarge (greater than 1) source element
ScaleTransform st = new ScaleTransform();
st.ScaleX = 1.4;
st.ScaleY = 1.4;
// set center of scaling to center of pushpin
st.CenterX = (pushpin as FrameworkElement).Height / 2;
st.CenterY = (pushpin as FrameworkElement).Height / 2;
pushpin.RenderTransform = st;
}
}
You have 2 ways to go:
(1) Create any UIElement to pass into PushPinLayer.AddChild. The AddChild method will accept and any UIElement, such as this Grid containing an Image and a TextBlock:
MapLayer m_PushpinLayer = new MapLayer();
Your_Map.Children.Add(m_PushpinLayer);
Image image = new Image();
image.Source = ResourceFile.GetBitmap("Images/Pushpin.png", From.This);
TextBlock textBlock = new TextBlock();
textBlock.Text = "My Pushpin";
Grid grid = new Grid();
grid.Children.Add(image);
grid.Children.Add(textBlock);
m_PushpinLayer.AddChild(grid,
new Microsoft.Maps.MapControl.Location(42.658, -71.137),
PositionOrigin.Center);
(2) Create a native PushPin object to pass into PushpinLayer.AddChild, but first set it's Template property. Note that PushPin's are ContentControls, and have a Template property that can be set from a Resource defined in XAML:
MapLayer m_PushpinLayer = new MapLayer();
Your_Map.Children.Add(m_PushpinLayer);
Pushpin pushpin = new Pushpin();
pushpin.Template = Application.Current.Resources["PushPinTemplate"]
as (ControlTemplate);
m_PushpinLayer.AddChild(pushpin,
new Microsoft.Maps.MapControl.Location(42.658, -71.137),
PositionOrigin.Center);
...
<ResourceDictionary
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<ControlTemplate x:Key="PushPinTemplate">
<Grid>
<Image Source="Images/Pushpin.png" />
<TextBlock Text="My Pushpin" />
</Grid>
</ControlTemplate>
</ResourceDictionary>
Good luck,
Jim McCurdy
Face To Face Software, and YinYangMoney