Background: My notebook is normally placed in a docking station, to which a big screen is connected. The icon for a (WPF) app is located on the screen of the notebook. Windows (7, 64 bit) opens the app on the notebook monitor instead of the big monitor.
I can move the icon onto the big monitor, and Windows will open the app on that monitor. But after starting the notebook not attached to the docking station, the icon is placed on the notebook's monitor again (and I'd actually prefer to have it there on the small screen)...
I found some code to programmatically set the location of the main window of the application, see How to set WPF window position in secondary display That works - but: only for the main window. All further windows are opened on the screen where the icon resides.
Now, I could specify the position for all other windows, too. Or I could write some code which stores the position when a window gets closed, remembering screen (preferred or other) also, and thus re-set it when the window gets loaded depending on available screens.
But that's overkill: actually, I just want to specify that the windows get opened some where on the big screen when that is available - I do not even care for the exact position on the screen (Windows could determine that the way it does now).
What simple solution can you suggest?
I suggest you create a new class which is inherits "Window" class, put your codes there in the new window , after that use it in all your windows.
Example:
using System.Windows;
namespace WpfApp2
{
public class Custom_Window_Class : Window
{
// Your code to reposition window (timer ...)
}
}
=================================
<local:Custom_Window_Class x:Class="WpfApp2.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:WpfApp2"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
</Grid>
</local:Custom_Window_Class>
======================================
namespace WpfApp2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Custom_Window_Class
{
public MainWindow()
{
InitializeComponent();
}
}
}
Unfortunately, I had to touch every single window to get things right - I'd like to call that a WTF.
In case of the type System.Windows.Window, the Owner property has to be set, plus its window.WindowStartupLocation = WindowStartupLocation.CenterOwner;. Again, that specifies more details than I wanted to specify.
In case of OpenFileDialog, the owner has to be provided in its ShowDialogmethod; with a MessageBox, in its Showmethod.
I think that it is far too much code for such a simple problem, and much more had to be specified than I actually wanted to specify. In the end, many WPF issues turn out to be WTFs.
Related
I have a frame control and it's source set to a page in xaml like this:
Source="/Myapp;component/MyFolder/Mypage.xaml"
Frame control shows the page when i run the application. But i want to see page displaying at frame control at design time.(Visual Studio 2017). It only shows a text like this: (/Myapp;component/MyFolder/Mypage.xaml)
This will work for a single page in design time.
Make sure you have the Blend namespace defined in your root xaml element.
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
Then add the d:DesignInstace attribute to your Frame.
<Frame d:DataContext="{d:DesignInstance Type=local:MyPage, IsDesignTimeCreatable=True}"
Content="{Binding}"/>
Then add something like this to your to the constructor where your Frame is hosted, after the InitializeComponent call.
public MainWindow()
{
InitializeComponent();
_frame.Content = null;
_frame.NavigationUIVisibility = NavigationUIVisibility.Visible;
_frame.Source = new Uri("/Wpf;component/MyPage.xaml", UriKind.Relative);
}
That should allow you to navigate with the Source property normally.
I've done lots of searching and found lots of answers but for some reason it's not working for me. I have a VB app in WPF. I want some common code for user controls.
So I make a base class like this:
Public Class cU
Inherits UserControl
Public Value As Double
End Class
And a user control, the Xaml starts like this:
<UserControl x:Class="UserControl3"
So all I have to do, as far as I can see, is to change this to:
<local:cU x:Class="UserControl3"
But although no error is shown in the Xaml window, I get and error in the error list:
"local" is an undeclared prefix. Line 1. position 2.' XML is not valid
(by the way, when I did exactly this in winrt it worked fine)
I tried changing it to local to Controls and also putting cU in a namespace called local but it doesn't change.
Add your namespace in your XAML for your window tag or control tag (depends whichever you are using).
<Window x:Class="YourNamespace.YourClass"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:YourNamespace">
then you can use the <local:UserControl3 /> tag
the YourNamespace in your case would be WpfApplication1
I've got a prism app, containing a Shell.xaml (with a MainRegion), ShellViewModel.cs.
This Shell window is opened when the app starts. Now I want to open a second Popup-Window containing the very same shell window (Shell.xaml, ShellViewModel).
The Shell definition is like in the prism StockTraderRI example. Shell.xaml contains a MainRegion (very simplified source):
<Window x:Class="Bsoft.Test.Shell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cal="http://www.codeplex.com/CompositeWPF"
Title="MainWindow" Height="550" Width="825">
<Grid>
<ContentControl cal:RegionManager.RegionName="MainRegion"/>
</Grid>
</Window>
Code behind contains just the basic ViewModel reference:
namespace Bsoft.Test.bmedApp
{
[Export]
public partial class Shell : Window
{
[ImportingConstructor]
public Shell()
{
InitializeComponent();
}
[Import]
ShellViewModel ViewModel
{
set
{
this.DataContext = value;
}
}
}
}
The ShellViewModel is automatically inserted by the MEF loader:
namespace Bsoft.Test.bmedApp
{
[Export]
public class ShellViewModel : NotificationObject
{
[ImportingConstructor]
public ShellViewModel()
{
}
}
}
This does work like intended.
Now I want to open the shell window a second time as a popup window. It's easy enough to mark the Shell and ViewModel as not being shared using:
[PartCreationPolicy(CreationPolicy.NonShared)]
But my problems are:
1) I load other View(Models) into the MainRegion. How do I tell the program if the View(Model) should be loaded into the main Shell MainRegion or into the popup window MainRegion? I guess I need scoped RegionManagers, but I got no clue how to use them for this.
2) I've got some events (EventAggregator) for the Views loaded into a region to communicate notification and commands (status update, view closing, errors) for the Shell to report. How can I seperate the main shell events from the popup window events (since both are the same shell)?
I want to be able to open several of the popup windows, so using different region names for both is not enough for me, I need more separation. Maybe there is a way to create a separate internal prism/mef/region/container framework??
I do not completely understand what do you mean by opening two shells ?
If you run your silverlight application in two different windows or you have 2 instances of your WPF app then your Shells do not conflict.
Even if you have one application with 2 instances of Bootstrapper there is no conflict - your two shells work completely independently.
Let me know whether this help.
What you are trying to achieve is possible, although there might be some things I don't completely understand about your approach.
I assume that when you are talking about having two Shells you actually mean having two active windows at the same time.
There are many ways to achieve this in Prism, so let's get on with your doubts.
For (1) the best thing I can think of is creating a different instance of the Region manager an attaching it to the other Shell (the popup one). This is similar to working with scoped regions (as you would have a separate RegionManager), but you create the manager and attach it to the Shell instead. Then register the new RegionManager in MEF with a string Id so you can differentiate it from the MainWindow RegionManager and simply add regions to the correct region manager.
(2) is a different subject, as you are trying to get the same code to behave differently. Perhaps, if you require such different behaviors, using the same Shell class for both windows is not the best approach. If you require this kind of differentiability but would still like to reuse code I'd recommend using some form of inheritance and combining virtual methods in a BaseShell with template methods to perform the things that are different for each Shell.
I hope this illustrates my point.
I have problem with control inheritance in WPF. I created a UserControl named BaseUserControl. I want for this control to be a base control for other WPF userControls. So I wrote another UserControl called FirstComponent. In next step I changed this code
FirstComponent : UserControl
to this
FirstComponent : BaseControl
However during compilation I get this error
Partial declarations of 'controlinheritance.componenets.FirstComponent' must not specify different base classes
What should I do to enable FirstComponent to derive from BaseControl?
EDIT
Thanks to abhishek answer I managed to inherit controls . Howerver I have another question. In base class I specified a property public Grid _MainGrid { get; set; }. Now I want in my derived class create an instance of this grid. So I used this code
Howerver I get an error Property '_MainGrid' does not have a value. Line 8 Position 36.
Did you see my complete article on it?
http://www.dotnetfunda.com/articles/article832-define-base-class-for-window--usercontrol-.aspx
I hope that would help you in this.
If you try to execute the project, it would definitely throw error to
you. This is because, every WPF window is created from the baseWindow
layout rather than the current Window layout. In other words, if you
see the XAML, you will see the root tag is Window, which is a class
just parent of the current window.
Thus to ensure everything works perfectly, we need to change the Root
Element.
So it would look like :
<local:BaseWindow Class="BaseWindowSample.Window1"
Name="winImp"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:BaseWindowSample"
Title="Window1">
...
</local:BaseWindow>
If you see this minutely, you can see I have added one namespace to my
project and named it as local. So BaseWindow should come from
BaseWindow and thus it goes like local:BaseWindow
Well the reason for the initial error was because the class was actually a partial class that was listing a particular base inheritance somewhere else in addition to the location where you changed your base class.
As for your property 'inheritance', I suggest trying
public Grid MainGrid
{
get
{
return base.MainGrid;
}
set
{
base.MainGrid = value;
}
}
However I should note that this will not give you a link to any existing instance(s) of your base class. If you want there to be a guaranteed link in your derived class to the lone instance of that Grid, then you will have to make the base class property a static.
In which case, your code will look like this...
public Grid MainGrid
{
get
{
return BaseControl.MainGrid;
}
set
{
BaseControl.MainGrid = value;
}
}
When you specify a Different base class for a Usercontrol in the XAML.cs file
FirstComponent : BaseControl
You should also change this in the XAML
<Base:BaseControl x:Class="FirstComponent"
xmlns:Base="clr-namespace:MyApplication.Base"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
</Grid>
</Base:BaseControl>
If I use Application.LoadComponent() to load a UserControl, Page or Window, my application freezes when I try to close it.
The app apparently closes, but the process keeps running. Easy to notice when debugging.
I've tested it under Windows 7 64bit and Vista 32bit. In both cases I have used VS2008 and .NET 3.5.
A repro can be built by creating a wpf application as follows:
public partial class Window1 : Window {
public Window1() {
InitializeComponent();
}
public void LoadCopy() {
var uri = new Uri("/WpfApplication1;component/window1.xaml", UriKind.Relative);
var copy = (Window)Application.LoadComponent(uri);
MessageBox.Show(copy.Title);
}
private void Button_Click(object sender, EventArgs e) {
LoadCopy();
}
}
Does anyone know what might be happening? And how to solve it?
Try assigning the owner to the created assembly i.e.
copy.Owner = this;
I was able to close your example after doing this.
I think it is because you are calling LoadComponent() on what is also your Main Window ( http://msdn.microsoft.com/en-us/library/system.windows.application.mainwindow.aspx ), i.e. the startup uri, in your case Window1. The program is probably entering some loop when you close it because closing a Main Window by default shuts down the Application and your two instances of Window1 are waiting on each other (A.K.A. a deadlock)! Albeit seemingly only after making the Application invisible (so it seems to have closed).
If you still must use use LoadComponent() on Window1 I think you would need to not make it your startup uri by changing the StartupUri of your Application:
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml"> <!-- change this -->
</Application>
Or change Application.ShutdownMode ( http://msdn.microsoft.com/en-us/library/system.windows.application.shutdownmode.aspx ) to OnLastWindowClose:
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml"
ShutdownMode="OnLastWindowClose">
</Application>
I have build you application on Windows 7 32bit under .Net 4.0 and 3.5.
I works fine for me. I think you problem is configuration specific.
Which configuration do you have? Do you reference any assemblies except default WPF project references?