Use difference XAML pages in XBAP - c#

How would I go about switching the main display XAML page that gets used in an XBAP. The only different is I want a larger mode and a smaller mode, but with the same controls (some hidden).

In your App.xaml.cs file, you can programmatically change which Window.xaml file you want to show on startup. Here is an over-simplified example.
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
System.Windows.Window startupWindow = null;
if(useLargeMode)
{
startupWindow = new LargeMainWindow();
}
else
{
startupWindow = new SmallMainWindow();
}
window.Show();
}
You can also do this by changing the StartupUri in your App.xaml file but that is obviously going to be harder to change at runtime.
<Application x:Class="Main.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml" /> <!-- change this -->
I've haven't tried binding to a property in the application declaration in the XAML, but VS 2010 doesn't complain about this. My concern would be that the app had it's datacontext set early enough for this to work correctly. Give it a try and let us know how it works. :)
<Application x:Class="Main.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="{Binding StartupWindow}">

Related

WPF - language changes only in MainWindow?

I've programmed a choose-language option in my project, using MergedDictionaries and project's settings. The issue is the language changes successfully only in my MainWindow, and not in other Windows as well. What am I doing wrong?
Set-language func in MainWindow (edit: MainWindow.cs):
/*set language*/
private void SetLanguageDictionary()
{
ResourceDictionary dict = new ResourceDictionary();
if (Properties.Settings.Default.Language.Equals("en")) //english was set
{
dict.Source = new Uri("\\res\\enDictionary.xaml", UriKind.Relative);
}
else //otherwise - hebrew as default lang.
{
dict.Source = new Uri("\\res\\hebDictionary.xaml", UriKind.Relative);
}
//add required dictionary to the MergedDictionaries
Resources.MergedDictionaries.Add(dict);
}
A small example of one of the Dictionaries [they are set symmetrically, if it matters]:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:UI_WPF"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<system:String x:Key="employees">Employees</system:String>
<system:String x:Key="employers">Employers</system:String>
<system:String x:Key="contracts">Contracts</system:String> </ResourceDictionary>
You haven't told us where the SetLanguageDictionary() method is defined but if you want to apply the resources globally you could merge the ResourceDictionary into the global Application.Current.Resources:
Application.Current.Resources.MergedDictionaries.Add(dict);
you know why language changes in MainWindow only? because when you call SetLanguageDictionary()only MainWindow will refresh(reload), and that why labels and texts will change. In order to change language in other window, you need to refresh them - reload them again- and during reloading process, content and labels will be updated.
you can call other window from MainWindow like below
window win = new window();
//then
win.AnyMethodyou_want();
new window() will reload window again, then language can be changed.
I have used this way before..

How to load content properly inside a ModernWindow using mvvm

At our company, we're used to develop our applications using WinForms,
Now we decided to switch to WPF-MVVM with Caliburn.Micro and Modern UI.
The thing we're trying to reach is to have a small application that has:
- 1 Modern Window
- 2 Pages inside that Modern window
the goal is to have a button inside that page that navigates the Modern Window to the second page with parameters.
I've been working trying to understand how to work this out, I succeeded with the Window (without the MUI), but when it comes to MUI, it's not really giving me the result we want.
So far, All I did, is
Create a new MUI Project
Add the Caliburn.Micro to the project
Change the App.xaml to
<Application x:Class="MuiWithCaliburn01.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MuiWithCaliburn01">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<local:AppBootstrapper x:Key="bootstrapper" />
<local:ModernContentLoader x:Key="ModernContentLoader" />
</ResourceDictionary>
<ResourceDictionary Source="/FirstFloor.ModernUI;component/Assets/ModernUI.xaml" />
<ResourceDictionary Source="/FirstFloor.ModernUI;component/Assets/ModernUI.Light.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Create the Bootstrapper Class
public class AppBootstrapper : BootstrapperBase
{
static AppBootstrapper()
{
}
public AppBootstrapper()
{
Initialize();
}
protected override void OnStartup(object sender, StartupEventArgs e)
{
DisplayRootViewFor();
}
}
Create the ModernContentLoader Class
public class ModernContentLoader : DefaultContentLoader
{
protected override object LoadContent(Uri uri)
{
var content = base.LoadContent(uri);
if (content == null)
return null;
var vm = Caliburn.Micro.ViewModelLocator.LocateForView(content);
if (vm == null)
return content;
if (content is DependencyObject)
{
Caliburn.Micro.ViewModelBinder.Bind(vm, content as DependencyObject, null);
}
return content;
}
}
ModernWindowView.xaml & ModernWindowViewModel.cs
< mui:ModernWindow x:Class="MuiWithCaliburn01.ModernWindowView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mui="http://firstfloorsoftware.com/ModernUI"
ContentLoader="{StaticResource ModernContentLoader}">
< mui:ModernWindow.MenuLinkGroups>
< mui:LinkGroupCollection>
< mui:LinkGroup DisplayName="Hello">
< mui:LinkGroup.Links>
< mui:Link Source="Child1View.xaml" DisplayName="Click me">< /mui:Link>
< /mui:LinkGroup.Links>
< /mui:LinkGroup>
< /mui:LinkGroupCollection>
< /mui:ModernWindow.MenuLinkGroups>
< /mui:ModernWindow>
class ModernWindowViewModel : Conductor.Collection.OneActive
{
public ModernWindowViewModel()
{
//this function is doing nothing in the ModernWindow, but it works great in the Window.
ActivateItem(new Child1ViewModel());
}
}
And finally, the Child1View.xaml
<UserControl x:Class="MuiWithCaliburn01.Child1View"
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"
xmlns:mui="http://firstfloorsoftware.com/ModernUI"
mc:Ignorable="d"
xmlns:cal="http://www.caliburnproject.org"
xmlns:model="clr-namespace:MuiWithCaliburn01"
d:DataContext="{x:Type model:Child1ViewModel}"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Button cal:Message.Attach="ClickMe" Width="140" Height="50">Hello World</Button>
</Grid>
</UserControl>
and Child1ViewModel.cs
public class Child1ViewModel : Conductor<IScreen>
{
public void ClickMe()
{
MessageBox.Show("Hello");
}
}
My question is, step 6, why does the function do nothing? and if my way is wrong can anybody direct me to a better way?
And if it's the best approach, how can I navigate from the function ClickMe to another View.
As for your first question about why does the function do nothing, I think it may have to do with the hierarchy of your project. Using MUI this is the main (and only) window for one of my applications
<mui:ModernWindow x:Class="namespace.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mui="http://firstfloorsoftware.com/ModernUI"
Title="Window Title" IsTitleVisible="True"
ContentSource="/Pages/Home.xaml"
Style="{StaticResource MyModernWindow}">
<mui:ModernWindow.TitleLinks>
<mui:Link DisplayName="settings" Source="/Pages/SettingsPage.xaml" />
</mui:ModernWindow.TitleLinks>
in my project hierarchy, i have my project root (CSPROJ file), MainWindow.xaml then a Pages folder. Inside my pages folder i have my SettingsPage.xaml. The source attribute in my mui:Link tag points to the realitive path of my main window to my settingsPage.xaml file. MUI will then load and display that path in the content provider that is put in your main window for you by the MUI ModernWindow class default style template. No additional code is needed on your part to navigate (until you want complex sub view navigation).
my settingsPage.xaml file is a normal user control with the grid having a style assigned to the ContentRoot static resource style as it also will contain additional views/pages.
Mui source can be found on GitHub at Mui GithubLink. Here you can download the sample program, who's code is found in the same repository under app Link here for covience.
I am not familiar with Caliburn.Micro so i'm not sure how the two integrate together, such as requirements of Caliburn.Micro to function. I do know how MUI integrates with MVVM light and there are many examples of this found on the internet in my research before hand.

Textbox created in WPF is not editable at run time

I am creating a WPF Window in which I have text boxes. However, when I run the project in Debug mode, (F5), I am not able to edit the text boxes that I created, nor am I able to choose from the listbox that I created. I googled, found that WPF and Win32 need to communicate to accept keyboard input, and got these 3 lines :
Window w = new Window1();
System.Windows.Forms.Integration.ElementHost.EnableModelessKeyboardInterop(w);
w.Show();
However, I am new to C# and hence I have absolutely no idea where to insert this C# code. I added the System.Windows.Forms and WindowsFormIntegration references to my project.
The window I am designing will be the first window that will appear at the launch of the application, hence I need the textboxes in this window to be editable without launching another window. Kindly guide me.
Edit : This is my XAML code:
<Window x:Name="Window1" x:Class="Myproject.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Risk Assessment"
Height="741" Width="1216.091">
<GroupBox x:Name="GroupBox1">
<Grid>
<TextBox x:Name="Length" IsReadOnly ="False" IsEnabled="True" />
</Grid>
</GroupBox>
</Window>
This is my C# code:
namespace Myproject
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
Edit 2: I modified the first line in the App.Xaml code like this :
<Application x:Class="Myproject.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="Application_Startup">
And in the App.Xaml.cs I added this snippet:
private void Application_Startup(object sender, StartupEventArgs e)
{
MainWindow win = new MainWindow();
ElementHost.EnableModelessKeyboardInterop(win);
win.Show();
System.Windows.Threading.Dispatcher.Run();
}
But still no luck. Where am I going wrong?
Try to change your Application.xaml to include the StartupUri:
<Application x:Class="Myproject.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml"
>
Remove all the startup code you had in the cs file.
Or
Change your cs code to this:
Window1 window1 = new Window1();
this.ShutdownMode = ShutdownMode.OnMainWindowClose;
this.MainWindow = window1;

Create Application from code and load resource dictionnary from xaml

This might be an extremely dumb question, but I simply can't understand the problem at the moment.
I have an App.xaml file that defines application level resources :
<Application x:Class="WpfMPManager.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="MyDictionnary.xaml"/>
</ResourceDictionary>
</Application.Resources>
For various reasons, I start this application through a .cs file like that (there actually is a lot more going on in this file).
[STAThread]
static void Main(params string[] args)
{
App myApp = new App();
MainWindow myWindow = new MainWindow();
myApp.Run(myWindow);
}
However, when I start the application in this way, my application resource dictionnaries are empty (and they are indeed filled if I start the application through my App.xml).
Should I call a specific method on the Application object to force it to load the resource dictionaries defined in the .xaml file ?
Thanks in advance.
Answering my own question in case anyone stumbles on that
It seems it's enough to call myApp.InitializeComponent() which is not called by the default constructor. Could have figured it out faster.

Expression Blend 4 accidently deleted App.xaml

Im new to Expression and by accident I deleted the App.xaml file. I think this is an important file and I cannot workout how to create an equivalent.
Please help,
Andy
Create a new project and copy that one.
<Application x:Class="Test.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
<Application.Resources>
</Application.Resources>
</Application>
Unless you had Application Resources defined, then you may be in trouble.
Might be a good argument for Source Control.
You can create a new Page and call it App.xaml.
Replace its markup as benPearce indicated with this:
<Application x:Class="Test.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
<Application.Resources>
</Application.Resources>
</Application>
Replace "Test" above with your namespace and "Window1" with the name of the first page you want shown in your project.
Replace the class in the App.xaml.cs code-behind with this:
public partial class App : Application
{
[STAThread]
public static void Main()
{
YourNamespace.App app = new YourNamespace.App();
app.InitializeComponent();
app.Run();
}
}
Ensure that your Project Properties are set in the "Application" area such that your startup object is YourNamespace.App.
Perform a build and you shouldn't get anymore errors related to 'App'.

Categories

Resources