As a workaround for the way Silverlight loads resources, I implemented the solution posted here:
Silverlight Shared MergedDictionaries
This works fine, but it's annoying having to comment out the resource dictionaries in the app.xaml. I need to comment them to run the app, but uncommenting them lets me get a design view.
I am sure there's a way to get the app to not load these, but I'm not much of a dev. Can somebody point me to a tutorial or example? Some googling hasn't turned up anything. Thanks!
I found a simple answer: comment out InitializeComponent in App().
Looking at the code in App.g.i.cs:
public void InitializeComponent() {
if (_contentLoaded) {
return;
}
_contentLoaded = true;
System.Windows.Application.LoadComponent(this, new System.Uri("/SLPortalResources;component/App.xaml", System.UriKind.Relative));
}
Since this just loads what's in app.xaml, commenting it out works: the app runs and you get a design view.
Is there anything wrong with doing this?
Related
The Short Version
How do you handle static resource look ups in UserControls that get embedded into other windows/user/custom controls? So that Blend 4 might render it properly # design time something Visual Studio already does for you.
The Long Version
As the question suggests, we have a window that has some embedded user controls and the window as well each as embedded user control all use static resource markup extensions to resolve references to resources found in a merged dictionary in the app.xaml file.
Blend has no problems loading and rendering any of my sample user controls that I made in the VS Designer Surface when opened individually. It has no problems resolving the countless static resource mark up extensions I employ pretty much everywhere.
Whenever I try to open my 'MainWindow.xml', (a window control) I noticed that I was getting 4 - Cannot Create Instance Of Type errors with Blend 4 nicely telling me on the ArtBoard that it has caught some design time exceptions. Digging further down into these exceptions by attaching the VS debugger instance to Blend I noticed that every single Static Resource I referenced, it complained it cannot find it.
As a comparison I looked at a custom control that I created, it did not employ any static resources at all they were local resources instead. This custom control when embedded into a UserControl I noticed worked pretty nicely. I think it is obvious why!
Does any one on SO, have any ideas how to get around this problem? I tried the whole 'Add a Design-Time Dictionary' <-- which works partially, embedded user controls still are not created at all !
Research
MVVM Light + Blend designer view error: Cannot find resource named 'Locator'
Theming using resources without Blend vomitting
UPDATE: Possible Solutions:
Employ a simialr approach presented here: GianlucaCucco Answer
Convert all static resource look ups to local resources for UserControls?
Convert all static resource look ups to dynamic resources instead.
Neither of these solutions are pretty. = (
I have several resources in a Converters.xaml file that Blend used to complain about. My workaround is to forcibly load that xaml file at design time.
using System;
using System.ComponentModel;
using System.IO;
using System.Windows;
using System.Windows.Markup;
public static class DesignTimeSupport
{
public static void LoadCommonConvertersForBlend(this ResourceDictionary resourceDictionary)
{
if (resourceDictionary == null || !DesignerProperties.IsInDesignTool) return;
var convertersXamlUri = new Uri("Assets/Converters.xaml", UriKind.Relative);
var streamInfo = Application.GetResourceStream(convertersXamlUri);
using (var reader = new StreamReader(streamInfo.Stream))
{
var converters = (ResourceDictionary)XamlReader.Load(reader.ReadToEnd());
resourceDictionary.MergedDictionaries.Add(converters);
}
}
}
The ViewBase calls this method in the constructor.
public class ViewBase : Page
{
public ViewBase()
{
Resources.LoadCommonConvertersForBlend();
}
}
Classes that don't inherit from ViewBase make their own call.
Try this answer -- it sounds like a similar problem. I've not had occasion to use it yet so I'm curious to know whether or not it works for you. It's certainly less messy than the other solutions.
As strange as it may seem (and I cannot find a logical reason why), the error message showed the resource it couldn't find as "maindictionary.xaml", whereas the file and all references were "MainDictionary.xaml".
I opened the properties of the resource in the Solution Explorer, changed the FileName to manidictionary.xaml, then back again to MainDictionary.xaml and the five error messages I was getting... disappeared.
Hope this answer finds its way into the hands of someone else who may be struggling with the oesoteric problem and it helps.
I'm following a small tutorial on how to switch pages in Silverlight. It can be found here:
http://jesseliberty.com/2008/05/31/multi-page-applications-in-silverlight/
It's slightly older, but everything worked.
The technique used here is to have a seperate page with a "Navigator function". If you're on Page1, you use something like this:
PageSwitcher ps = this.Parent as PageSwitcher;
ps.Navigate(new Page2());
With Navigate being the only function in PageSwitcher:
public void Navigate(UserControl nextPage) {
this.Content = nextPage;
}
Still, the way this is handled seems kind of odd. I'm still wondering what the difference is between adding a new User Control and Page. I've tried adding them both, they very much seem the same.
It seems like this is just using a hidden page to engineer the switching between the public pages. This seems somehow over the top to me. Is there an other way?
I think the difference between Page and UserControl is that Page has some Navigation methods like NavigationService.
For another way, check out Caliburn Micro's Screens and Conductors. It lets you do some advanced navigation stuff with little effort, check out the sample, HelloScreens. It adds life-cycle to your Screens. Also the ability to know when the view's been bound and nice stuff like that.
I'm facing a problem that I probably can't solve on my own, I'm working on a solution now for 2 days and browsed a lot in other Forums etc. - but it seems like that I just don't get it.
My problem
I have a Storyboard called "getVisible" in my UserControl "MainPage" that I want to access in another class called "test.cs"
However, as the Storyboard is defined in the MainPage.xaml and only the App Resources are accessible, do I face the problem that I can't load Storyboards from another class.
Any ideas how to solve that?
~regards Matt
One option to get the storyboard from test.cs is to create an instance of MainPage.
(new MainPage()).Resources["getVisible"];
Alternatively though, you may wish to consider creating the resources in a separate resource dictionary and then referencing that shared resource dictionary from both loactions.
My brain is all over the map trying to fully understand Unity right now. So I decided to just dive in and start adding it in a branch to see where it takes me. Surprisingly enough (or maybe not), I am stuck just getting my darn Application to load properly.
It seems like the right way to do this is to override OnStartup in App.cs. I've removed my StartupUri from App.xaml so it doesn't create my GUI XAML. My App.cs now looks something like this:
public partial class App : Application
{
private IUnityContainer container { get; set; }
protected override void OnStartup(StartupEventArgs e)
{
container = new UnityContainer();
GUI gui = new GUI();
gui.Show();
}
protected override void OnExit(ExitEventArgs e)
{
container.Dispose();
base.OnExit(e);
}
}
The problem is that nothing happens when I start the app! I put a breakpoint at the container assignment, and it never gets hit.
What am I missing? App.xaml is currently set to ApplicationDefinition, but I'd expect this to work because some sample Unity + WPF code I'm looking at (from Codeplex) does the exact same thing, except that it works!
I've also started the app by single-stepping, and it eventually hits the first line in App.xaml. When I step into this line, that's when the app just starts "running", but I don't see anything (and my breakpoint isn't hit). If I do the exact same thing in the sample application, stepping into App.xaml puts me right into OnStartup, which is what I'd expect to happen. Argh!
I've also just created a new WPF application from scratch, removed StartupUri, overrode OnStartup(), and it also works. WTH?
Is it a Bad Thing to just put the Unity construction in my GUI's Window_Loaded event handler? Does it really need to be at the App level?
Double check that the x:Class in App.xaml in the same namespace/class as in your App.xaml.cs. It's easy to copy/paste from another project and to forget to modify this.
If for any reason you don't manage to solve this, remove the App.xaml and add a Main() which does a new App().Run(). If this doesn't work either, there's something really odd here.
Your problem doesn't seem related to Unity at all... Make sure that :
the startup object is set to YourProject.App (in the project properties page)
the build action for App.xaml is set to "ApplicationDefinition"
Otherwise, I can't see any reason why it shouldn't work...
Update : just another idea... Try to set the StartupUri back to App.xaml, and call the base implementation in OnStartup :
protected override void OnStartup(StartupEventArgs e)
{
container = new UnityContainer();
base.OnStartup(e);
}
In my case, I hit the "something really odd" part that Julien Lebosquain referred to.
I kept checking and re-checking names, namespaces, event handlers etc and couldn't see anything wrong but still my WPF MainWindow.xaml kept opening first, bypassing the required startup method.
Eventually, I deleted MainWindow.xaml ... but STILL it popped up first. At which point, I cleaned the solution, deleted the binaries from disk (after altering the start-up project) and closed and re-opened the solution.
This 'fixed' my problem.
I had a similar problem -- My App constructor and OnStartup weren't being called (breakpoints not being hit). In case someone else runs across this thread, here's another thing that can go wrong.
I have a solution with several apps, one of which is just a utility I use to manage some XML files. It doesn't get used much, so I basically forgot about it. Originally, my builds were for "Any CPU", but recently I had to change them to "x86" due to a library I was using. Today, I needed to run this utility, but it was crashing and in the debugger nothing in the App class was being called. After checking namespaces (which were OK), I decided to clean the project (as suggested above). When I tried to run the app, I got an error that VS couldn't find the EXE. Apparently, VS was running an old "Any CPU" EXE it found in the output directory which was crashing, and then was deleted when I cleaned the project. I checked the Build | Configuration Manager, and sure enough, I hadn't selected the utility app for the "x86" build. Once I added it, everything worked great. Hope this helps.
In my first few hours with Silverlight 3, as an avid WPF user, I am greatly disappointed at the many things it doesn't support. This seems like an odd issue to me and it's so generic that I cannot find anything online about it.
I have the following XAML:
<controls:TabControl x:Name="workspacesTabControl" Grid.Row="1"
Background="AntiqueWhite" ItemsSource="{Binding Workspaces, ElementName=_root}"/>
However, I cannot see the workspacesTabControl in code-behind. I thought maybe IntelliSense is just being mean and tried to go ahead and compile it anyway, but got an error:
Error 1 The name 'workspacesTabControl' does not exist in the current context
How do I access controls in code-behind?
EDIT: I realized I've pasted the wrong error - I have two controls inside the UserControl called workspacesTabControl and menuStrip. I cannot get to either one of them by their name in the code-behind.
Just in case, here is the XAML for the menuStrip:
<controls:TreeView Grid.ColumnSpan="2" Height="100" x:Name="menuStrip"
ItemContainerStyle="{StaticResource MenuStripStyle}"
ItemsSource="{Binding Menu, ElementName=_root}"/>
EDIT AGAIN:
I'm not sure if this is helpful, but I've taken a look at the InitializeComponent() code and here's what I saw:
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public void InitializeComponent() {
if (_contentLoaded) {
return;
}
_contentLoaded = true;
System.Windows.Application.LoadComponent(this, new System.Uri("/SapphireApplication;component/SapphireMain.xaml", System.UriKind.Relative));
}
It seems that it simply loads the XAML when it runs (not before or during compilation) so the menuStrip and workspacesTabControl names don't actually get registered anywhere (as they usually are in WPF/win Forms). Could that attribute be a problem? And where do I get rid of this requirement for all the future UserControls I make?
Check the properties in VS for the xaml file itself... make sure the Build Action is set to Page.
As ridiculous as it may sound, I have resorted to using FindName() method to access named items in code-behind:
this.FindName("workspacesTabControl") as TabControl
I realize that this is a ridiculous way but I am forced to use this for now. Please let me know if someone else has encountered this problem and have come up with a better solution!
When you first create a control, Visual Studio does not pick it up with intellisense. However, after you try to build the project, it should become availble. You can also just type the name in without intellisense and then build it. Haven't verified this, but I heard this was on the list of things to fix in SL4.
That being said, if you name a control inside of a datatemplate, that control is not directly accessible in code-behind. This is the same for WPF, though.
You should be able to see it in the codebehind, that part works the same as WPF, maybe if you fix the problem with the menuStrip, then visual studio will be able to build the xaml paty of the page and ull be able to access the tabcontrol
I've seen the same problem in my Silverlight development. Specific to my problem my named controls were nested inside other controls (i.e. a datagrid) and I was unable to access them in my code behind. Any named controls at the same nesting level or above the previously mentioned datagrid worked fine but anything inside it was lost into the abyss.
As already mentioned, it should just appear in Intellisense, however the fact that you're getting an error related to something else, i.e. "menuStrip" is probably interfering with Intellisense. Resolve that error and you'l probably find that you can access the "workspacesTabControl" control.
Are you possibly using some sample code or something where they've named a control "menuStrip" and you've renamed it?
Good luck
Check that you don't have any controls using the same class name as a namespace name. For example:
namespace Solution.ProjectName.workspacesTabControl
{
public class workspacesTabControl
{
...
}
}
This will also give you this error.
Good luck,
Mark