WPF: XAML Custom Namespace - wpf

Okay so I have a Window in WPF. I add the following line inside of it:
xmlns:controls="clr-namespace:mCubed.Controls"
This compiles and runs just fine, but the Visual Studio designer gives me this error:
Could not load file or assembly 'mCubed, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
When I remove this line from the Window, it compiles and runs just fine and the Visual Studio designer works like a charm!
I'm confused as to why that one line breaks the designer? This occurs REGARDLESS if I have put the following line in the body of the XAML document.
<controls:MyControl/>
All my .cs files are in the same VS project. I have a mCubed namespace which contains my cleverly named mCubedWindow class. I have all my controls classes defined in the mCubed.Controls namespace. Do NOT tell me this is an assembly problem, ALL MY FILES ARE IN THE SAME VS PROJECT!

Not an assembly problem, just a designer problem. The VS WPF designer in 2008 is primitive at best - completely useless IMHO. I turn it off completely and use the XML editor instead. Hopefully things will improve drastically in 2010.

Is MyControl in the same assembly as the window? If it isn't, you need to include the assembly name in the declaration:
xmlns:controls="clr-namespace:mCubed.Controls;assembly=mCubed"

That's a bit weird. I've developed several projects that do exactly that. Here's a quick dummy project, all in one .exe:
First, a UserControl with a couple of buttons:
<UserControl x:Class="WpfApplication1.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid Width="30">
<Button HorizontalAlignment="Left">A</Button>
<Button HorizontalAlignment="Right">B</Button>
</Grid>
</UserControl>
Now the main window, with my control added to it:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:p="clr-namespace:WpfApplication1"
Title="Window1" Height="300" Width="300">
<Grid>
<p:UserControl1/>
</Grid>
</Window>
No error messages anywhere.

Is the XAML loose (Build action: None, No code behind) or compiled (Build action: Page, Can have code behind)?
If the XAML is loose or if MyControl is in a different assembly you must specify which assembly MyControl is in, like Daniel Pratt stated:
xmlns:controls="clr-namespace:mCubed.Controls;assembly=mCubed"
Make sure the assembly mCubed and its dependencies (references) are copied to your output directory. If they are not, then add mCubed as a reference to the start-up project.

Related

MahApps.Metro cannot load file or assembly in Visual Studio extension

I am using MahApps.Metro controls in my XAML code for the toolbox in Visual Studio Extension. I installed the package via NuGet, then I tried to add a control into my XAML markup. Below is the code snippet.
<UserControl
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:custom="http://metro.mahapps.com/winfx/xaml/controls"
x:Class="AutoDebug.MyControl"
Background="{DynamicResource VsBrush.Window}"
Foreground="{DynamicResource VsBrush.WindowText}"
mc:Ignorable="d"
d:DesignHeight="500" d:DesignWidth="400"
DataContext="{Binding UserControlModel}"
x:Name="AutoDebugWindow">
<Grid Margin="15">
<custom:Tile Content="Tile" HorizontalAlignment="Left" Margin="75,150,0,0" VerticalAlignment="Top" Background="#FF8B00BF"/>
</Grid>
</UserControl>
But I receive the following error no matter what.
A first chance exception of type 'System.Windows.Markup.XamlParseException' occurred in PresentationFramework.dll
Additional information: Could not load file or assembly 'MahApps.Metro, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
I have already tried installing/uninstalling, deleting/adding references but nothing has worked so far.
This is caused by the fact that MahApps.Metro is not included as a reference when the Visual Studio extension is compiled.
I'm not entirely sure why, but if you only use MahApps in XAML, then no reference is included in the compiled assembly. You can check this by unpackaging the extension (it's just a zip file), and opening the assembly in ILSpy. Under the references, MahApps will not be listed.
A workaround for this is to use MahApps somewhere in code. The simplest way to do this is to name the MahApps control that you are using. This generates a field for the control, and that seems to be enough to cause a reference to be included in the assembly.
<Grid Margin="15">
<custom:Tile x:Name="MyTile" />
</Grid>
You can also use an object from the MahApps assembly anywhere else in code (for example, you could create a new object in the constructor of the Package), but giving one of the controls a name is probably the simplest way.

windowsformhost cant load a usercontrol from another dll

So I have a dll from another project which contains many useful classes and controls for me (lets call it foo.dll). I'm making an WPF app. I need to use some of them in my app. I created my usercontrol for windows forms and referenced UserControlForMe from foo.dll. It's shown, all good. Now I want to insert my usercontrol into a wpf form. It looks like this:
<UserControl x:Class="FlatRectangular_Profile.UserControl1"
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"
xmlns:uc="clr-namespace:FlatRectangular_Profile.UC"
Height="2093" Width="717">
<Grid Name="grid">
<WindowsFormsHost>
<uc:WindowsFormsProfManual ></uc:WindowsFormsProfManual>
</WindowsFormsHost>
</Grid>
</UserControl>
But here I get an error "cant load type UserControlForMe from foo.dll". No info on that error. Again, UserControlForMe loads in WindowsFormsProfManual. All these is going on in one class library. I referenced everything that foo.dll needed.
No idea how what to do next. I also tried to load it in code in usercontrol.loaded event, but it fails too, and shows stacktrace which leads to the constructor of the UserControlForMe.
I guess you'll have to add the assembly to your namespace import to point your application in the right direction:
xmlns:uc="clr-namespace:FlatRectangular_Profile.UC;Assembly=MyDLL"
I found a workaround since I cant get why it is not working. If I load a UserControlForMe from foo.dll directly to the windowsformhost, it works. But if there is a "buffer" dll, it works in this dll, but doesnt open in futher window. Also I add a UserControlForMe programmatically to a windowsformhost.

IntelliSense for Data Binding not working - followup

Having got IntelliSense for Data Binding working in a simple test application, thanks to the answer to my previously raised question, I'm now trying to apply what I've learnt to the actual application I'm working on. Again I'm encountering problems that I don't understand. A snippet of my code is below - I've had to change names to protect propriety information:
<Page x:Class="MyProject.Views.Pages.MyPage"
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="450"
xmlns:Converters="clr-namespace:MyProject.Converters"
xmlns:ViewModels="clr-namespace:MyProject.ViewModels"
Title="My View"
SnapsToDevicePixels="True" KeepAlive="True" TextOptions.TextFormattingMode="Display">
<Page.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<Converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter"/>
</Page.Resources>
<StackPanel d:DataContext="{d:DesignInstance ViewModels:MyViewModel}">
<!-- ... -->
</StackPanel>
</Page>
I'm getting an error message on the line <StackPanel d:DataContext="{d:DesignInstance ViewModels:MyViewModel}">:
The name "MyViewModel" does not exist in the namespace "clr-namespace:MyProject.ViewModels".
The error doesn't make sense MyViewModel does exist within the MyProject.ViewModels namspace.
Any suggestions? I've tried a clean rebuild.
The MyProject.ViewModels namepsace is within a different assembly to the MyProject.Views.Pages and it appears to necessary to add ;assembly=MyProject.ViewModels to the xmlns:ViewModels="clr-namespace:MyProject.ViewModels delcaration:
xmlns:ViewModels="clr-namespace:MyProject.ViewModels;assembly=MyProject.ViewModels"
I assumed that because the assembly is referenced by the project, I wouldn't need to specify an assembly, just as I don't have to specify an assembly when using a namespace within a C# code file.
I just got the same error and I got it many times before. Each time I have this error, it come from the fact that I have other errors and my code won't compile for other reasons. As soon as I fixed all other errors, my code compile and VisualStudio find all 'd:' missing references... if they really exists.
Also, as an alternative, if you instanciate your ViewModel with its default constructor, I suggest to use something like (without using 'd:'):
...
</Page>
<Page.DataContext>
<ViewModels:MyViewModel/>
</Page.DataContext>
It will solve your problem forever.
I haven't tried it yet, but perhaps that with Roslyn (the new VS2015 compiler) this problem will go away. I hope :-)

View in a module not displaying image but it will display text

I am using MEF, Prism and WPF. I have a simple module (for now, I'll do more with it when I get past this roadblock) that displays a single image sourced as static resource in that module. Here is the xaml for the view:
<UserControl x:Class="SplashScreenModule.SplashView"
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"
Height="960" Width="1180">
<Grid>
<Label>
<Image Source="Images/My Image.png"/>
</Label>
</Grid>
The image shows up in the designer but when I run the code the window is blank. If I replace the image with simple text the text is display as expected.
<Label>
This shows up in the window.
</Label>
I've spent the last 3 hours trying to figure this out and am stumped. I would appreciate any help.
Thanks,
Bill
You have to know that there is a difference on how ressources are managed at DesignTime and at RunTime. At DesignTime there is no compilation required, thus it is able to display a ressource even if it is not include in the project.
At runtime this is normally possible, but it is better to include the ressources in your project (ie create a folder Images in your solution, and add the "My Image.png" in this folder), to be sure of the location of your ressource compared to your exe.
If you do it and the image still doesn't show up, try to remove the label and execute again.
By doing this it works fine for me. As soon as the image show up, you can add back the label.
Hope it helps.
The following code is working for me:
<Window x:Class="LabelImage.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>
<Label>
<Image Source="Images/visual studio.png" />
</Label>
</Grid>
</Window>
I structured my solution like you did: I have the picture inside a folder named Images. The MainWindow is located directly under the project node (it's not in any subdirectory).
Make sure that the Build Action for your image is set to resource, otherwise it won't work with the WPF Resource Finding System (which internally uses PACK-Uris: http://msdn.microsoft.com/en-us/library/aa970069(v=vs.110).aspx)
I use .NET 4.5 with VS 2013. If you have any further questions, please feel free to ask.
Update after Bill's comment:
That's a whole different thing when your resource resides within another assembly. The syntax for referencing the image should be like this:
<Image Source="/ClassLibraryForResources;component/Images/visual studio.png" />
where you do the following steps:
Begin with a slash "/"
Specify the name of the assembly that holds your resource (this can also be a strong assembly name)
Continue with ";component/"
End with the path of the image (or other resource)
(Please note that you have to omit the quotation marks).
The solution that I used is structured like this:
This should resemble what you have described. Again: it's all about the PACK URIs that WPF uses (see link above).

Application-level Resources in a Different Assembly

This question involves the Visual Studio (2008) WPF Designer's apparent inability to handle the usage of resources located at the App.xaml level if the App.xaml is in a separate assembly from the view.
To simplify the explanation of the problem I have created a test application. This application has two assemblies: View and Start. The View assembly contains a xaml window called Window1, and the Start assembly includes the App.xaml file. The App.xaml file in the Start assembly has its StartupUri set to the Window1 in the View assembly. Neither of these files have code-behinds (aside from the standard constructors and InitializeComponent() call).
The code for this example is as follows:
App.xaml:
<Application x:Class="Start.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="pack://application:,,,/View;component/Window1.xaml"
>
<Application.Resources>
<!-- Warning Text Style -->
<Style x:Key="WarningTextStyle" TargetType="TextBlock">
<Setter Property="FontWeight" Value="Bold" />
</Style>
</Application.Resources>
Window1.xaml:
<Window x:Class="View.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1"
Height="300"
Width="300"
>
<Grid>
<TextBlock Text="This is test text" Style="{StaticResource WarningTextStyle}" />
</Grid>
</Window>
The Window1.xaml file contains a single TextBlock that references the App-level WarningTextStyle. This code works fine at runtime because the Window properly finds the App-level resource; however, at design-time the designer complains that it cannot find the WarningTextStyle.
Does anybody know of a clean and scalable solution to this problem?
My standard approach with large applications is to organize my app-level resources into resource dictionary files, and then merge those dictionaries in the App.xaml. To work around the problem that I've described above I have to merge those resource dictionaries into each view's resources. This seems very inefficient, and if I later add another resource dictionary then I need to merge that new dictionary into every view.
A silver bullet solution would re-direct the designer to find the app-level resources. A reasonable work around would be the merging of the app-level resource dictionaries into each view, but only at design-time. At runtime I would like to avoid merging these dictionaries in every view because of the efficiency issues.
I've tried merging the dictionaries on each view in the view's code-behind constructor, and then wrapping that logic in an if statement that checks the DesignerProperties.GetIsInDesignMode() method; however, the Visual Studio designer does not run the view's constructor - so this approach appears to be a bust.
Does anybody have a better solution or work around?
Can you merge the resource dictionary in your referenced assembly (be it App.xaml or your own resource dictionary) from your main (exe) assembly's App.xaml?
I just had a different idea: use a DynamicResource instead of a Static one. This might introduce a tiny performance hit, but I doubt it would be measurable.

Resources