How to display a PictureBox from behind code in C# - c#

I know my question sounds basic, but i searched all over the place and found nothing..
this is my code :
public MainWindow()
{
InitializeComponent();
Map newMap = new Map();
newMap.setMapStrategy(new SmallMapStrategy());
newMap.createMap();
System.Windows.Forms.PictureBox pictureBox1 = new System.Windows.Forms.PictureBox();
pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(newMap.grid[3].afficher);
}
this is the afficher function :
public override void afficher(object sender, PaintEventArgs e)
{
e.Graphics.DrawImage(squareImage, pos_x, pos_y, 50, 50);
}
squareImage is an attribute corresponding to a Drawing.Image.
pos_x and pos_y are custom int32 attributes.
What i'd like is to SEE the image while running my application...

Since the PictureBox that you are using is a Winforms Control you will need to add a WindowsFormsHost Control to your Wpf Form and add the PictureBox to that. Any time you dynamically create a control you need to add it to the Form or Container object otherwise it will not be shown.
But first, add these references:
System.Windows.Forms
WindowsFormsIntegration
Now write code something like this.
MainWindow.xaml
<Window x:Class="WpfApplication1.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">
<Grid>
<WindowsFormsHost Height="175" HorizontalAlignment="Left" Margin="10,10,0,0" Name="windowsFormsHost1" VerticalAlignment="Top" Width="255" />
</Grid>
</Window>
MainWindow.xaml.cs
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
System.Windows.Forms.PictureBox picturebox1 = new System.Windows.Forms.PictureBox();
windowsFormsHost1.Child = picturebox1;
picturebox1.Paint += new System.Windows.Forms.PaintEventHandler(picturebox1_Paint);
}
void picturebox1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(#"C:\Temp\test.jpg");
System.Drawing.Point ulPoint = new System.Drawing.Point(0, 0);
e.Graphics.DrawImage(bmp,ulPoint);
}
}
}

Related

Wpf: Weirdly PreviewMouseDown event not firing inside a canvas

I have a problem with a PreviewMouseDown event. I have an app that does some complex drawing in a DrawingVisual which is later added on the canvas.
I've made a minimal working demonstration of the problem.
Steps to reproduce:
Run an app
Click Render
Click inside a red area.
PreviewMouseDown event on the Canvas is firing on the green area but doesn't fire at the red one. I really need to capture the mouse events inside this red area. How can this be accomplished?
Here the XAML:
<Window x:Class="MouseDownTest.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"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Button Grid.Row="0" Click="Button_Click">Render</Button>
<Canvas Grid.Row="1" x:Name="HostCanvas" PreviewMouseDown="HostCanvas_PreviewMouseDown"
Background="Green"
Width="300" Height="300"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
</Window>
And here is the code behind:
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
namespace MouseDownTest
{
public partial class MainWindow : Window
{
public class VisualHost : UIElement
{
public Visual Visual { get; set; }
public VisualHost(Visual childVisual) { Visual = childVisual; }
protected override int VisualChildrenCount => (Visual is null) ? 0 : 1;
protected override Visual GetVisualChild(int index) { return Visual; }
} // class VisualHost
public MainWindow() => InitializeComponent();
// Not FIRING inside a red square
private void HostCanvas_PreviewMouseDown(object sender, MouseButtonEventArgs e) => MessageBox.Show("Got a click!");
private void Render()
{
this.HostCanvas.Children.Clear();
this.HostCanvas.InvalidateVisual();
DrawingVisual vis = new();
using (DrawingContext dc = vis.RenderOpen())
{
var rect = new Rect(50, 50, 50, 50);
var redbrush = new SolidColorBrush(Colors.Red);
var redpen = new Pen(redbrush, 2);
dc.DrawRectangle(redbrush, redpen, rect);
}
var vh = new VisualHost(vis);
this.HostCanvas.Children.Add(vh);
System.Diagnostics.Debug.Assert(this.HostCanvas.Children.Count > 0);
}
private void Button_Click(object sender, RoutedEventArgs e) => Render();
}
}
So, how can I capture the mouse inside a red area and why exactly PreviewMouseDown is not firing?

How do I get WPF Window to stay on top of another?

Instead of using a traditional splash screen, I want to display a login window to allow the user to enter their credentials. Meanwhile, in the background, I want to initialize the app, then load the main window. The problem is that the login window is covered up by the main window once shown.
private void App_OnStartup(object sender, StartupEventArgs e)
{
Current.MainWindow = new LoginWindow();
Current.MainWindow.Show();
Task.Run(() => { /*do app startup background stuff*/ }).ContinueWith(t =>
{
var appWindow = new ApplicationWindow();
appWindow.Show();
Current.MainWindow.Owner = appWindow;
}, TaskScheduler.FromCurrentSynchronizationContext());
The login window is made the main window from the start. My assumption was that by setting the ApplicationWindow's owner to the login window, the login window would remain on top. If I'm doing it wrong, is there a way to achieve what I want? The topmost flag works but then the window is, well, topmost, which is undesirable.
Suppose you have a MainWindow:
<Window x:Class="SO40189046.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:SO40189046"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBlock Name="TimeText" />
</Grid>
</Window>
with code behind:
using System;
using System.Threading;
using System.Windows;
namespace SO40189046
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Loaded += MainWindow_Loaded;
// Background thread initializing the MainWindow
ThreadPool.QueueUserWorkItem((state) =>
{
for (int i = 0; i < 10; i++)
{
Dispatcher.Invoke(() =>
{
TimeText.Text = DateTime.Now.ToString();
});
Thread.Sleep(1000);
}
});
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
LoginWindow login = new LoginWindow();
login.Owner = App.Current.MainWindow;
login.WindowStartupLocation = WindowStartupLocation.CenterOwner;
if (!login.ShowDialog().GetValueOrDefault())
{
Close();
}
}
}
}
Then you can initialize your MainWindow while showing the login dialog.
AND you load the MainWindow as normal via StartUpUri in App.xaml

How to open the same instance of a previously closed window?

I implemented the control basics sample from the Kinect for Windows toolkit http://msdn.microsoft.com/en-us/library/dn188701.aspx to control the cursor with a users hand, but when I click on a sub window and then re open the main window with the hand cursor doesn't show.
My question is how do I open a new window without closing the previous window and then navigate back to the same instance of that window, not a new instance?
This is how I call a new window in my main window class:
private void trainingBtn_Click(object sender, RoutedEventArgs e)
{
var newForm = new TrainingFrm(); //create your new form.
newForm.Show(); //show the new form.
this.Close(); //only if you want to close the current form.
}
And this is how I reopen the main window, but it creates anew instance of the main window which I don't want.
private void homeBtn_Click(object sender, RoutedEventArgs e)
{
var newForm = new MainWindow(); //create your new form.
newForm.Show(); //show the new form.
this.Close(); //only if you want to close the current form.
}
What you need is composition
Here how it should look your mainWindow class
public partial class MainWindow : Window
{
private trainingWindow _trainingWindow;
public MainWindow()
{
InitializeComponent();
}
private void buttonGoTraining_Click(object sender, RoutedEventArgs e)
{
if (_trainingWindow== null)
{
_trainingWindow= new trainingWindow(this);
}
this.Visibility = Visibility.Hidden;
_trainingWindow.Show();
_trainingWindow.Visibility = Visibility.Visible;
this.Visibility = Visibility.Hidden;
}
}
and here is your training class
public partial class trainingWindow : Window
{
private MainWindow _mainWindow;
public trainingWindow(MainWindow mainWindow )
{
InitializeComponent();
_mainWindow = mainWindow;
}
private void biuttonBack_Click(object sender, RoutedEventArgs e)
{
this.Visibility = Visibility.Hidden;
_mainWindow.Visibility = Visibility.Visible;
}
}
here is the xaml
<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">
<Grid>
<Button Content="Button" Height="121" HorizontalAlignment="Left" Margin="112,38,0,0" Name="button1" VerticalAlignment="Top" Width="195" Click="buttonGoTraining_Click" />
</Grid>
</Window>
<Window x:Class="WpfApplication2.trainingWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="trainingWindow" Height="300" Width="300">
<Grid>
<Button Content="Button" Height="36" HorizontalAlignment="Left" Margin="52,33,0,0" Name="button1" VerticalAlignment="Top" Width="97" Click="biuttonBack_Click" />
</Grid>
</Window>
Simply hide it, and not close.
If you need to show a fresh information after show, just bind a new data to its view model.

Create controller from different classes, WPF C#

I am new in C# and trying to create some controller from my class
But unfortunately it is not showing in the window.
here is my code.
<Window x:Class="SWV_IT_V0._2.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" Loaded="Window_Loaded">
<Grid x:Name="MainGrid">
</Grid>
</Window>
public partial class MainWindow: Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
TextBlock txtBlock = new TextBlock();
txtBlock.Text = "Hello 1";
MainGrid.Children.Add(txtBlock);
ManageControlers myC = new ManageControlers();
}
}
When run this code I get "Hello 1" on my window
but when i try to create textblock from my class:
namespace SWV_IT_V0._2
{
public partial class ManageControlers : MainWindow
{
public TextBlock txtBlock;
public ManageControlers()
{
txtBlock = new TextBlock();
txtBlock.Text = "Hello 2";
MainGrid.Children.Add(txtBlock);
}
}
}
nothing show in window?
how is it possible to solve this problem?
Thanks in advance.
Try adding InitializeComponent(); to ManageControlersconstructor.
Through ManageControlers myC = new ManageControlers();, you are creating a new instance of your ManageControlers window, but you also need to show it via myC.ShowDialog();.

Using C#, can you drag a canvas in WPF?

Can you drag a canvas in WPF? How do you set the position of the canvas? Here is what I got so far:
/// xaml
<Window x:Class="TestApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="350" Width="525"
WindowStyle="None" ResizeMode="NoResize" AllowsTransparency="True"
Background="Transparent" Loaded="MainWindow_Loaded">
<Canvas Name="ParentCanvas" Background="#FF6E798D">
</Canvas>
</Window>
/// code behind
public partial class MainWindow : Window
{
private Boolean isMouseCapture;
public MainWindow()
{
InitializeComponent();
}
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
this.ParentCanvas.MouseLeftButtonDown += new MouseButtonEventHandler(_MouseLeftButtonDown);
this.ParentCanvas.MouseLeftButtonUp += new MouseButtonEventHandler(_MouseLeftButtonUp);
this.ParentCanvas.MouseMove += new MouseEventHandler(_MouseMove);
}
void _MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
this.ParentCanvas.ReleaseMouseCapture();
isMouseCapture = false;
}
void _MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
this.ParentCanvas.CaptureMouse();
isMouseCapture = true;
}
void _MouseMove(object sender, MouseEventArgs e)
{
if (isMouseCapture)
{
this.ParentCanvas.X= e.GetPosition(this).X;
this.ParentCanvas.Y = e.GetPosition(this).Y;
}
}
}
'X' is not a property of Canvas (i.e."this.ParentCanvas.X"). What do I use to set the position?
To set the position of an element in pixels, the element must be contained in a Canvas panel.
You can then call Canvas.SetTop and Canvas.SetLeft.

Categories

Resources