I've the following setup on my monitors:
I'm working on a screenshot app with C# - WPF and when i try to place the canvas on the monitor 3, it still loads in primary windows (monitor 2).
I tried Canvas.SetLeft and Canvas.SetTop using VirtualScreen.Left and VirtualScreen.Top (The values are OK, same values with the same situacion in another app in Java), but didn't work.
private void InitializeEditor()
{
var left = System.Windows.Forms.SystemInformation.VirtualScreen.Left;
var top = System.Windows.Forms.SystemInformation.VirtualScreen.Top;
var width = System.Windows.Forms.SystemInformation.VirtualScreen.Width;
var height = System.Windows.Forms.SystemInformation.VirtualScreen.Height;
MainCanvas = new Canvas();
MainCanvas.Background = Brushes.Black;
Content = MainCanvas;
MainImage = new Image();
Canvas.SetLeft(MainImage, 0);
Canvas.SetTop(MainImage, 0);
//Canvas.SetLeft(MainImage, left);
//Canvas.SetTop(MainImage, top);
SecondImage = new Image();
Canvas.SetLeft(SecondImage, 0);
Canvas.SetTop(SecondImage, 0);
//Canvas.SetLeft(SecondImage, left);
//Canvas.SetTop(SecondImage, top);
SecondImage.Opacity = 0.6;
SelectedArea = new();
screenshotAreaPickingState = new(this);
screenshotAreaMovingState = new(this);
freePenDrawingState = new FreePenDrawingState(MainCanvas);
lineState = new LineDrawingState(MainCanvas);
rectangleState = new RectangleDrawingState(MainCanvas, this);
arrowDrawingState = new ArrowDrawingState(MainCanvas);
textDrawingState = new TextDrawingState(MainCanvas);
var grid = new Grid();
if (this.Content != MainCanvas)
{
grid.Children.Add(MainCanvas);
}
CreateRectMenu();
}
Also Tried changing windows properties, but didn't work too
this.WindowStartupLocation = System.Windows.WindowStartupLocation.Manual;
this.Left = System.Windows.Forms.SystemInformation.VirtualScreen.Left;
this.Top = System.Windows.Forms.SystemInformation.VirtualScreen.Top;
this.Width = System.Windows.Forms.SystemInformation.VirtualScreen.Width;
this.Height = System.Windows.Forms.SystemInformation.VirtualScreen.Height;
this.WindowStyle = WindowStyle.None;
this.WindowState = WindowState.Minimized;
this.Visibility = Visibility.Hidden;
this.Topmost = true;
Unfortunately, there is no easy way to manipulate monitors in WPF. I am showing you an example based on the helper Nuget package https://www.nuget.org/packages/WpfScreenHelper
In the example, you can select any monitor in the ListBox and the window will be transferred to the selected monitor.
using WpfScreenHelper;
public class MonitorHelper
{
private Screen? selectedScreen;
public MonitorHelper()
{
Screens = Screen.AllScreens.ToArray();
}
public Screen[] Screens { get; }
public Screen? SelectedScreen
{
get => selectedScreen;
set
{
selectedScreen = value;
if (Window is not null)
{
Window.Left = value.WpfBounds.Left;
Window.Top = value.WpfBounds.Top;
}
}
}
public Window? Window { get; set; }
}
<Window x:Class="Core2024.SO.mr_k3p.question78800290.SelectMonitorWindow"
x:Name="wind"
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:Core2024.SO.mr_k3p.question78800290"
xmlns:wpfscreenhelper="clr-namespace:WpfScreenHelper;assembly=WpfScreenHelper"
mc:Ignorable="d"
Title="SelectMonitorWindow" Height="450" Width="1000"
DataContext="{DynamicResource helper}">
<Window.Resources>
<local:MonitorHelper x:Key="helper"
Window="{x:Reference wind}"/>
<DataTemplate DataType="{x:Type wpfscreenhelper:Screen}">
<UniformGrid>
<TextBlock Text="{Binding Bounds, StringFormat='Bounds={0}'}" Margin="10 0"/>
<TextBlock Text="{Binding DeviceName, StringFormat='DeviceName={0}'}" Margin="10 0"/>
<TextBlock Text="{Binding Primary, StringFormat='Primary={0}'}" Margin="10 0"/>
<TextBlock Text="{Binding ScaleFactor, StringFormat='ScaleFactor={0}'}" Margin="10 0"/>
<TextBlock Text="{Binding WorkingArea, StringFormat='WorkingArea={0}'}" Margin="10 0"/>
<TextBlock Text="{Binding WpfWorkingArea, StringFormat='WpfWorkingArea={0}'}" Margin="10 0"/>
<TextBlock Text="{Binding WpfBounds, StringFormat='WpfBounds={0}'}" Margin="10 0"/>
<TextBlock Text="{Binding WpfWorkingArea, StringFormat='WpfWorkingArea={0}'}" Margin="10 0"/>
</UniformGrid>
</DataTemplate>
</Window.Resources>
<StackPanel Margin="10">
<StackPanel Background="LightGreen">
<TextBlock Text="Full Virtual Area" FontWeight="Bold" HorizontalAlignment="Center"/>
<UniformGrid Rows="1">
<TextBlock Text="{Binding Path=(SystemParameters.VirtualScreenLeft), StringFormat='Left={0}'}"/>
<TextBlock Text="{Binding Path=(SystemParameters.VirtualScreenTop), StringFormat='Top={0}'}"/>
<TextBlock Text="{Binding Path=(SystemParameters.VirtualScreenWidth), StringFormat='Width={0}'}"/>
<TextBlock Text="{Binding Path=(SystemParameters.VirtualScreenHeight), StringFormat='Height={0}'}"/>
</UniformGrid>
</StackPanel>
<ListBox ItemsSource="{Binding Screens}"
SelectedItem="{Binding SelectedScreen}"/>
</StackPanel>
</Window>