Input dialogue popup on mouse click - c#

I'm trying to make it so when the user clicks on a spot in my canvas, a popup is displayed that allows the user to enter two separate pieces of data. So I need two textblocks and then a way to save the data entered into some variables in the code behind. I've been looking at different tutorials and it's easy making a window with input texblocks. Just not sure how to do it with popups. The addNode_MouseDown method is where I tried adding the popup, since the information entered is going to be about the circle that the user makes when they click on the canvas. Any help would be appreciated.
Here's my code at the moment:
XAML:
<Window x:Class="CanvasStuff.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Main Window" Height="410" Width="869">
<Grid Height="387">
<Label Content="Image" Height="32" HorizontalAlignment="Left" Margin="11,10,0,0"
Name="selectedFileName" VerticalAlignment="Top" Width="137"
Background="LightGray" BorderBrush="Gray" BorderThickness="1"/>
<Button Content="Browse File" Height="34" HorizontalAlignment="Left" Margin="154,6,0,0"
Name="BrowseButton" VerticalAlignment="Top" Width="119"
Foreground="Maroon" FontSize="16" FontFamily="Georgia" Click="BrowseButton_Click" />
<Button Content="Input Range and Heading" Height="34" HorizontalAlignment="Left" Margin="279,6,0,0"
Name="InputRangeBearing" VerticalAlignment="Top" Width="191"
Foreground="Maroon" FontSize="16" FontFamily="Georgia" Click="InputButton_Click" />
<Canvas Margin="0,45,2,8" x:Name="canvas1" MouseDown= "addNode_MouseDown">
</Canvas>
</Grid>
</Window>
Code behind:
namespace CanvasStuff
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
}
private void BrowseButton_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.InitialDirectory = "c:\\";
dlg.Filter = "Image files (*.jpg)|*.jpg|All Files (*.*)|*.*";
dlg.RestoreDirectory = true;
if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string selectedFileName = dlg.FileName;
ImageBrush brush = new ImageBrush();
brush.ImageSource = new BitmapImage(new Uri(selectedFileName));
canvas1.Background = brush;
BitmapImage bitmap = new BitmapImage();
}
}
private void InputButton_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Please click on known object to enter range and heading of that object.");
}
private void addNode_MouseDown(object sender, MouseButtonEventArgs e)
{
Point currentPoint = new Point();
if (e.ButtonState == MouseButtonState.Pressed)
currentPoint = e.GetPosition(this);
Ellipse ellipse = new Ellipse();
SolidColorBrush mySolidColorBrush = new SolidColorBrush();
mySolidColorBrush.Color = Color.FromArgb(255, 255, 255, 0);
ellipse.Fill = mySolidColorBrush;
ellipse.Width = 10;
ellipse.Height = 10;
Canvas.SetLeft(ellipse, e.GetPosition(canvas1).X);
Canvas.SetTop(ellipse, e.GetPosition(canvas1).Y);
canvas1.Children.Add(ellipse);
}
}
}

Did you try using the PopUp window?
XAML:
<Popup Name="errMsg" StaysOpen="False">
<TextBox/>
</Popup>
in your code behind:
errMsg.IsOpen = true;
Or you could either create fully using your code:
WPF popup window
Reference:
Popup a User Control

Related

WPF How can i do it with 1 event handler

I have a problem, i have 5 buttons that load txt files from system and show it as string on textblocks but i dont know how to do it without 5 event handlers
private void OnClick1(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
if (openFileDialog.ShowDialog() == true)
numbers1.Text = File.ReadAllText(openFileDialog.FileName);
}
OnClick1 is button1, numbers1 is a textblock1
now i have 5 codes like this (with numbers2.Text, numbers3.Text etc) how can i do it shorter
I may be misunderstanding what you are asking. However, if you want the different buttons to use the same click event. Then the click event is going to have to be able to distinguish “which” button was clicked in order to know which text box to use.
In this case, I recommend you give each button a name and then in the click event, cast the sender as a Button, then check its name to determine which text box to use. All buttons are wired up to this ONE (1) event. Example something like…
private void btn_Click(object sender, RoutedEventArgs e) {
Button btnSender = (Button)sender;
TextBox tb = null;
switch (btnSender.Name) {
case "btn1":
tb = txt1;
break;
case "btn2":
tb = txt2;
break;
case "btn3":
tb = txt3;
break;
case "btn4":
tb = txt4;
break;
}
if (tb != null) {
OpenFileDialog openFileDialog = new OpenFileDialog();
if (openFileDialog.ShowDialog() == true)
tb.Text = File.ReadAllText(openFileDialog.FileName);
}
}
This should get you started I think
private void btnLoad_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Multiselect = true;
List<TextBlock> textBlocks = new List<TextBlock>();
textBlocks.Add(txt1);
textBlocks.Add(txt2);
textBlocks.Add(txt3);
textBlocks.Add(txt4);
textBlocks.Add(txt5);
int count = 0;
if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
foreach (String files in openFileDialog.FileNames)
{
var currentText = textBlocks[count];
currentText.Text = File.ReadAllText(files);
count++;
}
}
}
Here is the xaml code
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" Margin="5">
<Button Name="btnLoad" Content="Load All" Click="btnLoad_Click" ></Button>
<TextBlock x:Name="txt1" HorizontalAlignment="Left" Margin="5" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="118"/>
<TextBlock x:Name="txt2" HorizontalAlignment="Left" Margin="5" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="118"/>
<TextBlock x:Name="txt3" HorizontalAlignment="Left" Margin="5" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="118"/>
<TextBlock x:Name="txt4" HorizontalAlignment="Left" Margin="5" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="118"/>
<TextBlock x:Name="txt5" HorizontalAlignment="Left" Margin="5" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="118"/>
</StackPanel>

Typing Button Content ON a Text Block (UWP)

In My project i have a Text Block
<TextBlock Name="MyDisplay" TextAlignment="Center"
Style="{StaticResource HeaderTextBlockStyle}"/>
And Set Of Buttons in a canvas
<Canvas Name="ButtonPanel">
<Button Style="{StaticResource MyButtonStyle}" Content="1" Canvas.Left="0" Canvas.Top="0"/>
<Button Style="{StaticResource MyButtonStyle}" Content="2" Canvas.Left="100" Canvas.Top="0"/>
<Button Style="{StaticResource MyButtonStyle}" Content="3" Canvas.Left="200" Canvas.Top="0"/>
<Button Style="{StaticResource MyButtonStyle}" Content="4" Canvas.Top="86" Canvas.Left="0"/>
<Button Style="{StaticResource MyButtonStyle}" Content="5" Canvas.Top="86" Canvas.Left="100"/> </Canvas>
I want to write button content in a text block
My code is
public DisplayPad()
{
this.InitializeComponent();
ButtonPanel.AddHandler(PointerPressedEvent, new PointerEventHandler(ScreenMarkup_PointerPressed), true);
UpdateDisplay();
}
public void ScreenMarkup_PointerPressed(object sender, RoutedEventArgs e)
{
Button button = e.OriginalSource as Button;
if (button == null)
return;
string content = button.Content.ToString();
double digit;
if (double.TryParse(content, out digit))
{
if(content == "1")
{
//codes
MyDisplay.Text = "1";
}
}
UpdateDisplay();
}
void UpdateDisplay()
{
try
{
MyDisplay.Foreground = Application.Current.Resources["ApplicationForegroundThemeBrush"] as Brush;
// Update the display
MyDisplay.Text = String.Format("{0:##.##}");
}
catch
{
//Exception
}
}
But this code is not working it is not update number in TextBlock.
But same thing is used in windows phone 8 which was working fine but only difference in code is (Windows phone 8 code)
public DisplayPad()
{
this.InitializeComponent();
ButtonPanel.AddHandler(Button.MouseLeftButtonUpEvent, new MouseButtonEventHandler(ScreenMarkupButton_MouseLeftButtonUp), true);
UpdateDisplay();
}
public void ScreenMarkupButton_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
Button button = e.OriginalSource as Button;
if (button == null)
return;
string content = button.Content.ToString();
double digit;
if (double.TryParse(content, out digit))
{
//My Codes
}
UpdateDisplay();
}
The OriginalSource object is not a Button but rather the inner TextBlock within the Button, so you need to change your code to
var textBlock = e.OriginalSource as TextBlock;
if (textBlock == null)
return;
string content = textBlock.Text;

How to remove a DropShadowEffect in code?

I have a method which draws lines in a canvas like this:
public void drawoncanvas(double[] coord, string fullkey)
{
myLine = new Line();
myLine.X1 = coord[0];
myLine.X2 = coord[2];
myLine.Y1 = coord[1];
myLine.Y2 = coord[3];
MainWindow.mycanvas.Children.Add(myLine);
myLine.MouseEnter += mymouse; //add MousEnter Event
myLine.MouseLeave += mymouseleave; //add MouseLeave Event
}
The MouseEnter Event then adds a DropShadowEffect to the line that triggers the event:
public void mymouse(object sender, MouseEventArgs e)
{
Line thisline = sender as Line;
thisline.Effect = new DropShadowEffect{Color = new Color { A = 255, R = 255, G = 255, B = 0 }, Direction = 320,ShadowDepth = 0, Opacity = 1};
}
This works fine. But now I want to remove this effect as soon as the mouse cursor is not anymore over the line:
public void mymouseleave(object sender, MouseEventArgs e)
{
Line thisline = sender as Line;
thisline.Effect = null; //this doesn't do anything
}
I know this is a is probably a really simple question but I couldn't find any solution so far.
EDIT:
Ok I found what causes the problem, still don't know a solution though: I don't only create the dropshadow in the MouseEnter event but also display a tootltip, so my full Code is actually:
public void drawoncanvas(double[] coord, string fullkey)
{
myLine = new Line();
myLine.Stroke = Brushes.Red;
myLine.X1 = coord[0];
myLine.X2 = coord[2];
myLine.Y1 = coord[1];
myLine.Y2 = coord[3];
myLine.Tag = fullkey;
MainWindow.mycanvas.Children.Add(myLine);
myLine.MouseEnter += mymouse;
myLine.MouseLeave += mymouseleave;
}
ToolTip tt = new ToolTip();
public void mymouse(object sender, MouseEventArgs e)
{
Line thisline = sender as Line;
string data = Convert.ToString(thisline.Tag);
string[] splitdata = data.Split('/');
tt.Content = String.Concat(splitdata[0], " -> ", splitdata[3] ,"kt -> ", splitdata[1]);
tt.StaysOpen = false;
tt.IsOpen = true; //the removing of the shadow on MouseLeave works when I comment this line out
thisline.Effect = new DropShadowEffect{Color = new Color { A = 255, R = 255, G = 255, B = 0 }, Direction = 320,ShadowDepth = 0, Opacity = 1};
}
public void mymouseleave(object sender, MouseEventArgs e)
{
Line thisline = sender as Line;
tt.IsOpen = false;
thisline.Effect = null;
}
If I simply comment out the tt.IsOpen = true; and do not display the tooltip it all works fine.....I'm really confused.
EDIT 2:
Here the XAML:
<Window x:Class="mapO1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:mapO1"
Title="mapO1" Height="600" Width="750" WindowStartupLocation="CenterScreen" SizeChanged="MainWindow_SizeChanged">
<Grid>
<Grid x:Name="mygrid">
<local:ZoomBorder x:Name="border" ClipToBounds="True" Background="Black">
<Grid Name="maingrid">
<Image Name="image1" />
<Canvas Name="mycanvas" HorizontalAlignment="Left" VerticalAlignment="Top" ClipToBounds="False"/>
</Grid>
</local:ZoomBorder>
<Button x:Name="button1" Content="Fullscreen on/off" HorizontalAlignment="Right" Height="18" Margin="0,20,50,0" VerticalAlignment="Top" Opacity="0.5" Width="108" FontWeight="Bold" Click="button1_Click"/>
<ComboBox x:Name="comboBox1" Height="24" HorizontalAlignment="Left" VerticalAlignment="Top" Width="150" Margin="10,20,0,0" Opacity="0.5" FontWeight="Bold" Text="Select Period" SelectionChanged="comboBox1_SelectionChanged"/>
<ComboBox x:Name="comboBox2" Height="24" HorizontalAlignment="Left" VerticalAlignment="Top" Width="150" Margin="10,60,0,0" FontWeight="Bold" Opacity="0.5" Text="Select Stream" DropDownClosed="comboBox2_DropDownClosed"/>
</Grid>
</Grid>
</Window>

Crop Image using Canvas Rectangle

Cropping the image is not working properly. Where I'm wrong?
My Xaml :
<Grid x:Name="Gridimage1">
<Image Name="image1" Grid.Column="0" Height="317" HorizontalAlignment="Left" Margin="20,67,0,0" Stretch="Fill" VerticalAlignment="Top" Width="331"></Image>
<Canvas x:Name="BackPanel">
<Rectangle x:Name="selectionRectangle" Stroke="LightBlue" Fill="#220000FF" Visibility="Collapsed" />
</Canvas>
</Grid>
<Button Content=">>" Height="23" HorizontalAlignment="Left" Margin="357,201,0,0" Name="Go" VerticalAlignment="Top" Width="41" Click="Go_Click" FontWeight="Bold" Visibility="Hidden" />
<Image Grid.Column="1" Height="317" HorizontalAlignment="Left" Margin="408,67,0,0" Name="image2" Stretch="Fill" VerticalAlignment="Top" Width="331" />
C# :
private bool isDragging = false;
private Point anchorPoint = new Point();
public MainWindow()
{
InitializeComponent();
Gridimage1.MouseLeftButtonDown += new MouseButtonEventHandler(image1_MouseLeftButtonDown);
Gridimage1.MouseMove += new MouseEventHandler(image1_MouseMove);
Gridimage1.MouseLeftButtonUp += new MouseButtonEventHandler(image1_MouseLeftButtonUp);
Go.IsEnabled = false;
image2.Source = null;
}
private void Go_Click(object sender, RoutedEventArgs e)
{
if (image1.Source != null)
{
Rect rect1 = new Rect(Canvas.GetLeft(selectionRectangle), Canvas.GetTop(selectionRectangle), selectionRectangle.Width, selectionRectangle.Height);
System.Windows.Int32Rect rcFrom = new System.Windows.Int32Rect();
rcFrom.X = (int)((rect1.X) * (image1.Source.Width) /(image1.Width));
rcFrom.Y = (int)((rect1.Y) *(image1.Source.Height) / (image1.Height));
rcFrom.Width = (int)((rect1.Width) * (image1.Source.Width) /(image1.Width));
rcFrom.Height = (int)((rect1.Height) * (image1.Source.Height) /(image1.Height));
BitmapSource bs = new CroppedBitmap(image1.Source as BitmapSource, rcFrom);
image2.Source = bs;
}
}
#region "Mouse events"
private void image1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (isDragging == false)
{
anchorPoint.X = e.GetPosition(BackPanel).X;
anchorPoint.Y = e.GetPosition(BackPanel).Y;
isDragging = true;
}
}
private void image1_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging)
{
double x = e.GetPosition(BackPanel).X;
double y = e.GetPosition(BackPanel).Y;
selectionRectangle.SetValue(Canvas.LeftProperty, Math.Min(x, anchorPoint.X));
selectionRectangle.SetValue(Canvas.TopProperty, Math.Min(y, anchorPoint.Y));
selectionRectangle.Width = Math.Abs(x - anchorPoint.X);
selectionRectangle.Height = Math.Abs(y - anchorPoint.Y);
if (selectionRectangle.Visibility != Visibility.Visible)
selectionRectangle.Visibility = Visibility.Visible;
}
}
private void image1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (isDragging)
{
isDragging = false;
if(selectionRectangle.Width >0)
{
Go.Visibility = System.Windows.Visibility.Visible;
Go.IsEnabled = true;
}
if (selectionRectangle.Visibility != Visibility.Visible)
selectionRectangle.Visibility = Visibility.Visible;
}
}
private void RestRect()
{
selectionRectangle.Visibility = Visibility.Collapsed;
isDragging = false;
}
#endregion
It is cropping the wrong part.
The Margin property was not set properly to the Canvas control. It should be the same as Image control's margin properly value. If we don't set Margin to Canvas, It will take the full window size.
Xaml
<Grid x:Name="Gridimage1" Margin="0,0,411,100">
<Image Name="image1" Grid.Column="0" Height="317" HorizontalAlignment="Left" Margin="20,67,0,0" Stretch="Fill" VerticalAlignment="Top" Width="331">
</Image>
<Canvas x:Name="BackPanel" Margin="20,67,0,0">
<Rectangle x:Name="selectionRectangle" Stroke="LightBlue" Fill="#220000FF" Visibility="Collapsed" />
</Canvas>
</Grid>
<Grid x:Name="other">
<Button Content=">>" Height="23" HorizontalAlignment="Left" Margin="341,152,0,0" Name="Go" VerticalAlignment="Top" Width="41" Click="Go_Click" FontWeight="Bold" />
<Image Height="317" HorizontalAlignment="Left" Margin="403,10,-217,-7" Name="image2" Stretch="Fill" VerticalAlignment="Top" Width="331" />
</Grid>
</Grid>

How can i get all the buttons in the uniformgrid and scroll it to see them all?

i am building an application to show all the software installed in the computer, i already have all the buttons to show with the respective icon, but when i show them, the uniformgrid only shows the buttons that fit in to the window, i thought a scrollbar will show them, but i get to the end of the window and the buttons still missing! how can i show them all with a scrollbar?
Here is the XAML code:
<Window x:Class="apple.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow">
<Grid>
<DockPanel Name="dock">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<UniformGrid Name="gridx" DockPanel.Dock="Top" Rows="7" Columns="7">
</UniformGrid>
</ScrollViewer>
</DockPanel>
</Grid>
</Window>
Here is the c# code:
namespace apple
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public string[] link = Directory.GetFiles(#"C:\ProgramData\Microsoft\Windows\Start Menu\Programs", "*.lnk", SearchOption.AllDirectories);
public MainWindow()
{
this.ResizeMode = ResizeMode.NoResize;
//this.WindowStyle = WindowStyle.None;
this.WindowState = WindowState.Maximized;
InitializeComponent();
masterGUI();
}
public void masterGUI()
{
gridx.Height = System.Windows.SystemParameters.PrimaryScreenHeight;
IconImage[] ico = null;
Bitmap[] img = null;
string[] list = null;
list = new string[link.Length];
ico = new Icon[link.Length];
img = new Bitmap[link.Length];
for (int n = 0; n < link.Length; n++)
{
ImageBrush ib = new ImageBrush();
System.Windows.Controls.Button newBtn = new Button();
list[n] = System.IO.Path.GetFileNameWithoutExtension(link[n]);
FileToImageIconConverter some = new FileToImageIconConverter(link[n]);
ImageSource imgSource = some.Icon;
ib.ImageSource = imgSource;
newBtn.Name = "a" + n;
newBtn.Background = ib;
newBtn.Content = list[n];
newBtn.Click += new RoutedEventHandler(newBtn_Click);
gridx.Children.Add(newBtn);
}
}
private void newBtn_Click(object sender, RoutedEventArgs e)
{
Button clicked = (Button)sender;
string test = null;
test = clicked.Name.Replace("a","0");
this.Close();
System.Diagnostics.Process.Start(link[Int32.Parse(test)]);
}
}
}
Remove the Grid and DockPanel and set either UniformGrid.Rows or UniformGrid.Columns, not both. All you need is Window, ScrollViewer, and UniformGrid:
<Window>
<ScrollViewer>
<UniformGrid Name="gridx" Columns="7"/>
</ScrollViewer>
</Window>
And to do it in a more idiomatic WPF fashion, you should have something like this:
<Window>
<ScrollViewer>
<ItemsControl ItemsSource="{Binding Programs}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="7"/>
You would then expose a Programs collection from your data source and would thus automatically generate an item for each installed program.

Categories