ResourceDictionary.MergedDictionaries causes weird errors - c#

Inside my WPF Application I am including a ResourceDictionary from another Project.
<Application x:Class="namespace.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- This Line causes an Error -->
<ResourceDictionary Source="pack://application:,,,/Commons;Component/Generic.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
Metadata override and base metadata must be of the same type or derived type.
The solution builds successful and runs.
Restarting Visual Studio doesn't fix it.
Cut and Paste the <ResourceDictionary Source="..." /> line causes another error as explained here in the Comments:
Value Cannot be Null. Parameter Name: item. Restarting Visual Studio will then bring back the old error.
Sadly I haven't found out how to reproduce this error, I can only tell you something more about the environment im using:
Visual Studio 2015 Professional, Version 14.0.25431.01 Update 3
And allthough I doubt, those are associated with my problem, here my installed Plugins:
Resharper Ultimate 2017.1.1
GitExtensions Version 2.49.03

Sinatr's comment hinted me to read more about theming.
ThemeInfo
Inside of a Custom Control Library theres automatically created a ThemeInfoAttribute inside AssemblyInfo.cs
[assembly:ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
Parameters
As it states in the autogenerated comments, the first parameter is to determine wheter there exist or where to find Theme specific resource dictionaries.
The second parameter defines wheter there exist or where to find the generic ResourceDictionary (Generic.xaml).
ResourceDictionaryLocation-Enumeration
The ResourceDictionaryLocation-Enumeration itself is used to specify the location of those dictionaries.
ResourceDictionaryLocation.None
No theme dictionaries exist.
ResourceDictionaryLocation.SourceAssembly
Theme dictionaries exist in the assembly that defines the types being themed.
This expects the ResourceDictionary to be located in a /Themes-Folder. Explanation later.
ResourceDictionaryLocation.ExternalAssembly
Theme dictionaries exist in assemblies external to the one defining the types being themed.
I am not going to explain how this works.
Why /Themes-Folder
Sadly I couldn't find too much about this. If someone has some more info please share.
Have you ever wondered, how styles of a lookless control are being applied?
If one created a lookless Control, he did as follows:
public class MyControl : ControlTemplate
{
static MyControl()
{
// This tells WPF to search for a Style for this type
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyControl)),
new FrameworkPropertyMetadata(typeof(MyControl)));
}
}
In short, Ressources in WPF are located, by searching up the Logical-Tree, then inside Application's Resources and finally inside sth. they call System-Area (this is my translation from German, if you know a better one pls tell).
So depending on ThemeInfo, MyControl propably had its Style inside a ResourceDictionary inside the /Themes-Folder, eg. /Themes/Generic.xaml. And that tells WPF to add the Ressources to the System-Area which finally results in automatically resolving the appropriate style.
Somewhere inside /Themes/Generic.xaml:
<Style TargetType="{x:Type MyControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MyControl}">
..
</ControlTemplate/>
</Setter.Value>
</Setter>
</Style>
That's why the above ThemeInfoAttribute requires Generic.xaml to be located in a /Themes-Folder. - And somehow, even if in my case the System-Area-Functionality isn't even used for this generic file, this causes those errors. But I wasn't able to find out why.
Sources:
ThemeInfoAttribute Constructor
ResourceDictionaryLocation Enumeration
Windows Presentation Foundation - Das Umfassende Handbuch, Rheinwerk Computing Version 4

Related

Unable to Resolve Resources

I am using the MaterialDesign for XAML package in WPF. When I run my application, all styles and controls are rendered as expected. However in the XAML designer I have dozes of errors such as "The resource 'MaterialDesignFlatButton' could not be resolved." Example of a line that is throwing that error:
<Button Style="{StaticResource MaterialDesignFlatButton}" IsDefault="True" Margin="0 8 8 0" ...
My app.xaml contents is as follows:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.Blue.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.LightBlue.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
I have attempted the top solution proposed on The resource "x" could not be resolved. but that causes the project to fail to run (I believe I am not using the correct pathing when attempting to use the proposed "absolute pack URI"). So I have two questions at this point:
Is there a reason the resources would fail to resolve in the XAML designer given the way I have defined them in App.xaml (per the developer guide: https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/wiki/Getting-Started)?
How can I find out the "absolute pack URI" to use for the source for my resource dictionaries?
In the past, I had problems like this.
The error causes are as follow.
1. Setup and setting config
About this, please check the github and material design homepage.
2. Build and Compiler problem
About this, users may set the "Platform Target" as "x64".
That can invoke errors because material designer tool use "x32" compiler, so please use "any cpu" or "x32".
I had this problem with the flat accent button, while every other button style worked. I added the resource for buttons, then the error was gone. Then I removed the button resource... and the error was still gone.
https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/wiki/FAQ
Exception: Cannot find resource named 'MaterialDesign...'
This error typically comes when you have a static resource referencing
one of the material design styles, and have not included the
appropriate resource dictionary that contains the style. Try the
following:
Ensure that you have loaded all of the default material design styles in your App.xaml. You can find directions for this in the
Getting Started guide.
Ensure you have referenced the control specific resource dictionary that contains the style. The path for this is resource dictionary
should be .xaml" />. For example, if you were trying to reference the
MaterialDesignFloatingActionMiniButton style for a button, the
resource dictionary source would be: . Typically these inclusions are done at root of your Window, User
Control, or Template. You can find the full list of the resource
dictionaries here

Unable to override default style of wpf control in generic.xaml

So we are trying to retemplate some stock wpf controls by changing their default styles in the generic.xaml
When we normally do this we subclass a control and then override the default style key of the subclassed control in its static initializer. However, we are trying to just override the basic control now without subclassing it. That way anyone in the company using the stock wpf control will get our new styling by default.
I can't seem to get this to work though.
In my sandbox application which is a watered down version of our actual problem, I have the following.
MainWindow.xaml
<StackPanel>
<TextBlock>It doesn't work</TextBlock>
<local:CustomTextBlock>It works</local:CustomTextBlock>
</StackPanel>
Themes/Generic.xaml
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontSize" Value="100" />
</Style>
<Style TargetType="{x:Type test:CustomTextBlock}">
<Setter Property="FontSize" Value="100" />
</Style>
CustomTextBlock.cs
public class CustomTextBlock : TextBlock
{
static CustomTextBlock()
{
Type _CustomTextBlock = typeof(CustomTextBlock);
DefaultStyleKeyProperty.OverrideMetadata(
_CustomTextBlock,
new FrameworkPropertyMetadata(_CustomTextBlock));
}
}
Which results in this being displayed.
My theory is that the WPF engine is ignoring our style because the default style key is either A: not overridden or B: is finding their style in their generic.xaml first.
My question is, is there a work around for this? Are my assumptions correct?
UPDATE:
According to reference source, the default style key is overridden in the stock wpf control for TextBlock.cs in this case
Reference Source TextBlock.cs (Line 346)
To accomplish this, you can put your styles either directly into App.xaml or into a separate ResourceDictionary (named DefaultStyles.xaml).
Putting directly into App.xaml is easy enough, just put the style within the Resources element.
If you want to put the styles into a file (this is useful if you want the styles for multiple applications or within multiple assemblies) you add it to the MergedDictionaries of your App.xaml as such
<Application x:Class="MyAwesomeApp"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Themes/DefaultStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
This assumes that you put the file DefaultStyles into the Themes folder. If it is in another assembly you would do the following:
<ResourceDictionary Source="/Company.Controls.UI;component/DefaultStyles.xaml"/>
Have a look at this post (What is so special about Generic.xaml).
The main issue seems to be:
WPF looks for the default style in a special resource dictionary in the Themes folder in the same assembly as the control.
'Your' control is defined in 'your' assembly, TextBlock is defined in PresentationFramework. So you better create another ResourceDictionary for re-styling standard controls and include/merge it in each of your xaml documents (I suppose, this hurts).
Hope it helps.

WPF MergedDictionaries - Value Cannot be Null - Parameter Name: item

I am having a nagging issue with my App.Resources MergedDictionary. Every time add a new dictionary with a source and XML namespace from another assembly, an error is produced and I cannot build my program.
The error appears in App.xaml with the ResourceDictionary underlined and the message Value Cannot be Null. Parameter Name: item. This makes absolutely no sense as I have done the exact same thing before. The only difference is that this time, I am referencing the namespace of another assembly(c# class library). Here is the App.xaml file:
<Application x:Class="Quiz.Client.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Quiz.Client"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Styles.xaml" />
<ResourceDictionary Source="Resources/Templates.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
Below is Styles.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Quiz.Client">
<Style x:Key="StrongFont"
TargetType="ContentControl">
<Setter Property="FontSize"
Value="20" />
<Setter Property="FontWeight"
Value="ExtraBold" />
<Setter Property="Foreground"
Value="DarkRed" />
</Style>
</ResourceDictionary>
Here is Templates.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Quiz.Client"
xmlns:domain="clr-namespace:Quiz.Core.Domain;assembly=Quiz.Core"
xmlns:common="clr-namespace:Quiz.Client.Common">
<DataTemplate x:Key="ArithmeticQuestionTemplate"
DataType="domain:ArithmeticQuestion">
</DataTemplate>
<common:QuestionTemplateSelector x:Key="QuestionTemplateSelector"
ArithmeticTemplate="{StaticResource ArithmeticQuestionTemplate}" />
</ResourceDictionary>
What the heck is going on? Was there a software-breaking change introduced or something? I am completely lost.
Confirm!!! This bug is tracked by Microsoft. This mean WPF in some points will is trying to report to Microsoft automatically with Microsoft report process. During the report VS start freeze. Please, wait bug report to finish.
The bug still exist in lattes VS 2019.
After restart everything is fine. Confirm!!!
Thanks for the answer. I believe it is a Visual Studio bug caused by something unknown. Maybe one of my plugins, who knows. The only thing that fixes the issue is restarting visual studio and building the project. The problem seems to begin when adding a new namespace from another assembly. The project then can't build until visual studio is restarted. Very weird, never seen anything like it before. – user3096803
Not sure why your method isn't working but it's not how I usually import resources myself. Typically I'll add a ResourceDictionary to my library project, put all the libraries resources in that and import it into my main project using pack syntax:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MyLibrary;component/LibraryResources.xaml" />
</ResourceDictionary.MergedDictionaries>
<!-- main project resources go here -->
</ResourceDictionary>
In general I'd argue that this is a better architecture anyway as it doesn't require a re-compile of your main project each time one of the child library resources change. It also makes it easier later on if you decide to switch to MEF, as your library resources are now encapsulated in a single ResourceDictionary object that you can readily [Export].
I don't really understand the answer from #Pit but I tried restarting visual studios and also changing all source paths to full pack URIs, and nothing seemed to work. Came across this thread that hinted at using Tools > Options > Preview Features > New WPF XAML Designer for .NET Framework which fixed the issue for me.
EDIT: This "fix" may have been a red herring, it still had issues but they were equally cryptic! After switching back to the old XAML designer and doing some further digging I found that one of my merged dictionaries was incompatible with the wpf designer and it was resulting in this error. The fix on that page resolved my issue.
This specific fix probably won't help anyone, but hopefully the methodology will. Check if there are any errors in any of the individual resource dictionaries in the merged dictionaries.

Have default string resource file and override it with custom ones

So the title is perhaps not completly clear.
I have a Strings.xaml file which contains several strings which are used in the application.
Strings.xaml
<!-- GENERAL FOR ALL TESTS -->
<my:String x:Key="AppTitle">AppName</my:String>
<my:String x:Key="TestName1">test_1</my:String>
<my:String x:Key="TestName2">test_2</my:String>
<!-- DEFAULT MESSAGES -->
<my:String x:Key="TestMessage">This is a default message</my:String>
<my:String x:Key="TestDescription">This is a default description</my:String>
<my:String x:Key="OnlyCustomInTest2">This string is used as a default message if not overridden by custom resource file</my:String>
</ResourceDictionary>
This resource file works great. What I'm wondering is if there is any built in way that I can use Strings.xaml as a default resource file and then override specific strings that are custom for different program modes? Like having Strings.xaml default and use Test_1_Strings.xaml and Test_2_Strings.xaml to override some strings for custom messages.
Test_1_Strings.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:System;assembly=mscorlib">
<!-- CUSTOM FOR TEST 1 -->
<my:String x:Key="TestMessage">This is a message for test 1</my:String>
<my:String x:Key="TestDescription">This is a description for test 2</my:String>
</ResourceDictionary>
Test_2_Strings.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:System;assembly=mscorlib">
<!-- CUSTOM FOR TEST 2 -->
<my:String x:Key="TestMessage">This is a message for test 2</my:String>
<my:String x:Key="TestDescription">This is a description for test 2</my:String>
<my:String x:Key="OnlyCustomInTest2">This is the overridden message for test 2</my:String>
</ResourceDictionary>
The reason I want to do this is because I have many different program modes where most of the resources are the same but some are custom. Instead of having to change a shared entry in 8 different resource files I could do it in only one place.
Resource lookup in WPF traverses from bottom to top i.e. any resource usage will first look for resource in its parent container which can be Grid, StackPanel etc. If not found in parent container will look for resource in parent's parent container and so on to UserControl, Window till it reach App resources.
Also, any resource later defined under resources section overrides the resource added previously with same key. This is true for resources defined under different resource dictionaries but not within the same XAML file. If you try to declare two items with same key, it will fail with key already exists exception.
You can take advantage of above stated features to your use.
Assuming you are merging the resources under App resources, what you can do is add Strings.xaml at top and then add other resource dictionaries Test_1_Strings.xaml and Test_2_Strings.xaml. This way resources with same name will be overridden and resource defined at last will always be resolved.
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Strings.xaml"/>
<ResourceDictionary Source="Test_1_Strings.xaml"/>
<ResourceDictionary Source="Test_2_Strings.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
So when you declare TextBlock to refer to StaticResource TestMessage.
<TextBlock Text="{StaticResource TestMessage}"/>
it will print This is a message for test 2.
If you change the order and add Test_1 after Test_2, textBlock Text will be - This is a message for test 1.

Silverlight defaultStyle problem

I have the following scenario:
Create a new class library project called Lib1
1.1. Add a new control called control1, Themes/generic.xaml file and specify
the default style of control1.
Create a new class library project called lib2.
2.1.Add a new control called control2, Themes/generic.xaml file and specify
the default style of control2. In the dafaultStyle of control2 I use control1.
My question is: Do I have to copy/paste the defaultStyle xaml of control1 into the
generic.xaml of lib2, to use control1 with its style applied in control2?
The default style lookup for a Control is always done in the assembly that the Control is defined in. So if Control1 is defined in Lib1.dll, the default style will always be looked for in generic.xaml in Lib1.dll. It doesn't matter where the Control is being used from.
Just to make sure I understand your answer correctly, I will restate it in my own words:
You want to have a Silverlight class
library (Lib1) that houses a control
(Control1).
You want to have a
Silverlight class library (Lib2)
that houses a control (Control2).
You want to have the control use their respective generic.xaml files for respective control styles.
Control2 is to include Control1 in its style definition, without redefining its style in the generic.xaml file from Lib2.
If this is correct, I will describe my answer below:
Yes, this is possible as Keith Mahoney said here. I will go into detail on his answer and an example.
Each Silverlight class library generates a Dynamic-link library (dll) when compiled. All the classes (controls) and resources (styles) are contained in these dll's. Thus, when you create a lib1 class library with a style resource for a control contained within, it will all be stored in the lib1 dll.
Below is my example of the solution:
Setting up the solution:
First, I created new solution (StackOverflow Example.sln). Then I added a new project to the solution of type Silverlight Class Library (Lib1 1.1). Please note that Silverlight does not always play nicely with spaces in the namespace, so you may want to (as I did) rename the namespace to Lib1. See "How-To's" section for details on how to do this. Next I added the second project to the solution of type Silverlight Class Library (Lib2 2.1). I again, changed the root namespace of this project to one without spaces. Finally, I added a Silverlight Application project to my solution (SLApplication). Please note that in adding the Silverlight application project, you will be prompted to add a web project or web page to your project for creating the Silverlight control. Either option will work, please use the best for your situation. I used the separate website option (default). Now, when we setup the two class libraries, we were given a default starter class1.vb file. Let's rename these file to Control1.vb (for Lib1 1.1) and Control2.vb (for Lib2 2.1) in the solution explorer. When we do this, Visual Studio 2008 asks us if we'd like it to rename the class to match this new name, Click 'Yes'. Next up, let's figure out how to setup the themes for each of our controls.
Setting up themes:
I will start with the first control library (Lib1 1.1). First, create a new folder under the root of the project; name it "Themes" (case doesn't matter). Under this folder, add a new item of type xml and name it generic.xaml. For help on how to do this, see the "How-To's" section. Open the generic.xaml file, if it isn't already open. Delete the xml declaration text that was automatically inserted for you, and use the following for your initial definition:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- Styles go here. -->
</ResourceDictionary>
Now, since our Control1 control lives in this class library, we will need to add an xml namespace declaration (xmlns) (http://en.wikipedia.org/wiki/XML_namespace -sorry about the non link, my rep needs to be higher.) to our generic.xaml file. To do this, add the following line: xmlns:lib1="clr-namespace:Lib1" before the grater than symbol (>) in the top declaration. Once this is done, we can layout a simple style. Please note that we're setting the default background color to "Red" in order to differentiate the two controls. Please see below for the simple style for Control1:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:lib1="clr-namespace:Lib1">
<!-- Style for Control1 -->
<Style TargetType="lib1:Control1">
<Setter Property="Background" Value="Red" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="lib1:Control1">
<Grid x:Name="LayoutGrid" Background="{TemplateBinding Background}">
<TextBlock Text="Control 1" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
With this let's start with the Control2. This will be very similar to the previous declaration for Lib1 1.1. If you haven't already done so, please add the Themes folder and the generic.xaml file as you did for the first library (Lib1 1.1). Now, for this project, you will need a reference to the Lib1 1.1 project. If you need help doing this, please see the "How To's" section. Once this is referenced, open the generic.xaml file, if it isn't already open. The definition of this file is almost identical; however, we will also be referencing the other projects namespace as well. See below:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:lib2="clr-namespace:Lib2"
xmlns:lib1="clr-namespace:Lib1;assembly=Lib1">
<!-- Styles go here. -->
</ResourceDictionary>
Notice that now we are not only referencing our own namespace (lib2) but also referencing the other control's namespace (lib1) in the xml namespace declaration. Also notice that in the non-local control library, we also must reference the assembly name. Since we want to use the control (and its style) from lib one, we will need a place to use it in this project. For this, I have setup a grid with separate rows for each control. Please note that we're setting the default background color to "Blue" in order to differentiate the two controls. Please see below for Control2's definition:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:lib2="clr-namespace:Lib2"
xmlns:lib1="clr-namespace:Lib1;assembly=Lib1">
<!-- Style for Control2 -->
<Style TargetType="lib2:Control2">
<Setter Property="Background" Value="Blue" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="lib2:Control2">
<Grid x:Name="LayoutGrid">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<lib1:Control1 Grid.Row="0" />
<Grid x:Name="Control2" Grid.Row="1" Background="{TemplateBinding Background}">
<TextBlock Text="{TemplateBinding Text}" />
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
This just sets up the fact that we want to have styles. We now need to tell Silverlight that we want these styles to be applied to our controls.
Using themes:
In our classes, we have to tell Silverlight that these are going to be custom user controls, to do this, we need to inherit from Control (or any other UIElement control - for this example, we will stay simple, and use Control). In order to tell the control to use a style defined in the generic.xaml, we need to do this in our constructor of each control.
For Control1:
Public Sub New()
MyBase.DefaultStyleKey = GetType(Control1)
End Sub
For Control2:
Public Sub New()
MyBase.DefaultStyleKey = GetType(Control2)
End Sub
Now all we have to do now, is tell our web site to use our new control(Control2).
Setting up the WebApplication:
You will need to reference both class libraries from your web project. See "How-To's" section for details on how to do this. Open up the Page.xaml file in your web application project (SLApplication). Your default should look something like this:
<UserControl x:Class="SLApplication.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
</Grid>
</UserControl>
We will add to this the xml namespace declaration for our Silverlight class library (Lib2 2.1) so that we may reference Control2. Now that we have referenced our class library, we can use any controls that are declared within. If you try to use the namespace without building after you add it to your xmlns declaration, you may not see any declared classes (controls) within. To fix this, build once. Please also note, that Visual Studio 2008 is sometimes weird about custom libraries, and may generate an error that says the custom library is not defined. This is fixed with a re-launch of the solution (Close Visual Studio and reopen). The final code to show the Control2 (which contains Control1) is as follows:
<UserControl x:Class="SLApplication.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:lib2="clr-namespace:Lib2;assembly=Lib2"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
<lib2:Control2 />
</Grid>
</UserControl>
Now build, and run. If everything went well, you should see the following:
Screen Shot http://www.imagefrog.net/out.php/i40631_StackOverflowExample.jpg
The full project can be downloaded from Google Code:
http://code.google.com/p/stackoverflow-answers-by-scott/wiki/1366075
Zipped source:
http://stackoverflow-answers-by-scott.googlecode.com/files/1366075.zip
Enjoy!
How-To's:
Change project namespace
In the solution explorer expand the project on which you want to change the namespace, and double click on the "My Project". For Silverlight class library projects, you will have four tabs on the left, one of which is "Silverlight". Select this tab, if it is not already selected. Under the "Root namespace" textbox, change the namespace to your desired namespace.
Add 'generic.xaml' to project
In the solution explorer, right click on the project name. Click "Add", and then click "New Folder". This will create a folder under the root of the project. Name this folder "themes". Please note that case does not matter here. Right click on the "themes" folder, click "Add", then click "New Item...". A dialog box appears for you to select what item type you want to add. Click "XML File" under the Templates section. Change the name to generic.xaml under the name field (at the bottom of the dialog). Click Add.
Create a project reference
To create a project reference, right click on the project that needs the reference. Select "Add Reference..." from the menu. A dialog box will be displayed for you to choose the reference to add. Select the "Projects" tab at the top of this dialog. Select the desired project reference. If you do not see the project that you want to reference in this list, check that you have added the project to the solution.

Categories

Resources