Get Assembly where instance is declared in XAML - wpf

I have a framework.dll, customerFramework.dll and customer.exe.
Inside of the framework.dll is a customControl declared which can be placed in customerFramework.dll (in a XAML page/window) or in customer.exe (in a XAML page/window).
The customControl got a public DependencyProperty of type Uri. Visual Studio supports IntelliSense for its resources, so it is very easy to set these properties.
During runtime, the CustomControl tries to resolve the resources inside of framework.dll, but they are declared in:
customer.exe
To fix this issue, I have to set the following prefix: /customer;component/ballon.svg.
customerFramework.dll
To fix this issue, I have to set the following prefix: /customerFramework;component/ballon.svg.
But if I do so, I don't have any IntelliSense. So I would like to combine the right uri by adding the prefix in code behind.
What I want to know is the assembly name inside of the customControl, where the customControl has been placed.
If the customControl is placed in customerFramework.dll and I use the Assembly.() methods, I get the wrong informations (expected value: customerFramework):
GetEntryAssembly(): customer.exe
GetCallingAssembly(): framework.dll
GetExecutingAssembly(): framework.dll
Is there a hidden function to get this information?

sorry man i misunderstood the question .
please use reflection with stacktrace
var currentAssembly = Assembly.GetExecutingAssembly();
var callerAssemblies = new StackTrace().GetFrames()
.Select(x => x.GetMethod().ReflectedType.Assembly).Distinct()
.Where(x => x.GetReferencedAssemblies().Any(y => y.FullName == currentAssembly.FullName));
var initialAssembly = callerAssemblies.Last();
Code will be slow because it use reflection . good luck.

Related

Why Can't I Use My DbContext Type?

I'd like to access some static properties of my DbContext type in a WPF Window. I thought I could use the same XAML that I use to refer to individual entities:
<Window.Resources>
<entity:Account x:Key="account"/> //Works fine
<entity:MyEntities x:Key="myEntities"/> //Throws an error!
</Window.Resources>
I get this error:
No connection string named 'MyEntities' could be found in the application config file.
Why is it treating the DbContext type (MyEntities) differently than the Account entity? Is there an easy way I can access the static properties of my MyEntities type?
The syntax you used is for creating instances, not static properties. If you want to access a static property you need to use the x:Static markup extension
<Window.Resources>
<entity:Account x:Key="account" SomeProperty={x:Static entity:MyEntities.MyProperty}/>
</Window.Resources>
The above xaml would be similar to the C# code
var account = new Account()
{
SomeProperty = MyEntities.MyProperty
};
this.Resources["account"] = account;
See that you are calling new Account(), if you called new MyEntites() (like your original example did) you get the error you where getting.
It appears that particular error results due to the static constructor that I placed in my DbContext. When I remove the static constructor the error changes to:
Object reference not set to an instance of an object.
As it turns out, the original error doesn't prevent me from compiling or running my application. I changed my code to use Scott Chamberlain's suggestion (which produces a similar ignorable error) because it is much cleaner and I can access the static properties on the DbContext just fine in spite of Visual Studio's complaints. Thanks, everyone, for the help and suggestions.

Design Time - Dynamic

can i create a view at design time, using dynamic objects? (with visual studio 2010)
for example, or something, is that possible?
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dyn="clr-namespace:System.Dynamic;assembly=System.Core"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
and
<d:DesignProperties.DataContext>
<dyn:ExpandoObject>
<dyn:ExpandoObject.Name>MyName</dyn:ExpandoObject.Name>
</dyn:ExpandoObject>
</d:DesignProperties.DataContext>
The above example does not work.
Sometimes I have class complicated to manage. And I can not use them at design time, the idea of using a dynamic type would be not to change the bindings (properties that I will use) and get a vision.
I do not know if I was clear, but if you have something that can help me would be great.
That should not work in any case, be it design or run-time.
You can use ExpandoObjects, but only via dictionary syntax:
<dyn:ExpandoObject>
<sys:String x:Key="Name">MyName</sys:String>
</dyn:ExpandoObject>
Though i do not know if that junk of a GUI designer is able to handle that, nor do i know if this works with compiled XAML.
Edit: As i thought you cannot compile this because some component fails:
Error 1 The Key attribute can only be used on a tag contained in a Dictionary (such as a ResourceDictionary).
Well, it is a bloody dictionary alright...
You can use a markup extension though, you can get the DictionaryFactoryExtension from this answer and modify it like this:
public override object ProvideValue(IServiceProvider serviceProvider)
{
var expando = (IDictionary<string,object>)new ExpandoObject();
foreach (DictionaryEntry kvp in Dictionary)
expando[(string)kvp.Key] = kvp.Value;
return expando;
}
//The designer uses this for whatever reason...
public object this[object key]
{
get { return this.Dictionary[key]; }
set { this.Dictionary[key] = value; }
}
Then you can use that just like an ExpandoObject:
<!-- Of course you can also hard-code the key-type in the class,
it should be a string in all cases when using an ExpandoObject anyway -->
<local:DictionaryFactory KeyType="sys:String" ValueType="sys:Object">
<sys:String x:Key="Name">MyName</sys:String>
</local:DictionaryFactory>
The designer should be able to handle this.

Making Silverlight 2 programs work in Silverlight 4

I am trying to make Jeff's testing program, written in Silverlight 2 (http://www.jeff.wilcox.name/2008/03/silverlight2-unit-testing/), work using Silverlight 4 and VS2010 and I get a NullReferenceException at this line:
chatSession.ConnectWithRemoteUser("ScottGu");
Any ideas why? Here's code:
public Page()
{
// commented out because it doesn't exist in the current context
// according to the compiler
// InitializeComponent();
// Retrieve ChatSession instance from XAML resource declaration
chatSession = new ChatSession();
chatSession = (ChatSession)Resources["ChatSessionDS"];
// Connect with Chat Server to chat with "ScottGu"
chatSession.ConnectWithRemoteUser("ScottGu");
}
First, if you had to comment out InitializeComponent(), I Feel bad about your application: InitializeComponent is generated by the VS tools when the XAML file of your page is parsed.
If it doesn't exist, it probably means that the class declared in the xaml file is different from the one in your c# file (different name or different namespace) Otherwise, maybe the XAML file action type in the VS property tab isn't set to "page".
second:
chatSession = new ChatSession();
chatSession = (ChatSession)Resources["ChatSessionDS"];
this looks strange.you create a new ChatSession, then replace it by an object saved in the page resources. Why do you create it firstplace if you put the instance out of scope at the next line?

Silverlight InlineCollection.Add(InlineUIContainer) missing?

I'm having difficulty adding the inline of specific type InlineUIContainer into the InlineCollection (Content property) of a TextBlock. It appears the .Add() method of InlineCollection doesn't accept this type, however you can clearly set it through XAML without explicitly marking the content as a InlineContainer, as demonstrated in many examples:
http://msdn.microsoft.com/en-us/library/system.windows.documents.inlineuicontainer.aspx
Is it possible to programatically add one of these as in the following?
Target.Inlines.Add(new Run() { Text = "Test" });
Target.Inlines.Add(new InlineUIContainer() {
Child = new Image() { Source = new BitmapImage(new Uri("http://example.com/someimage.jpg")) } });
Target.Inlines.Add(new Run() { Text = "TestEnd" });
I have a feeling what's going on is that Silverlight is using a value converter to create the runs when specified in XAML as in the example which doesn't use InlineContainer, but I'm not sure where to look to find out.
The specific error I'm getting is as follows:
Cannot add value of type 'System.Windows.Documents.InlineUIContainer' to a 'InlineCollection' in a 'System.Windows.Controls.TextBlock'.
As pointed out by Jedidja, we need to use RichTextBox to do this in Silverlight.
You can't Add() Runs directly, but you can add Spans containing Runs.
Interestingly, you can also do this:
textBlock.Inlines.Clear();
textBlock.Inlines.Add(new Span());
textBlock.Inlines[0] = new Run();
Not that it's a good idea to hack around what the framework is actively trying to prevent you from doing.
P.S. If you can't figure out what XAML is doing, inspect the visual tree.

Creating WPF ResourceDictionary from code doesn't seem to work when setting ResourceDictionary.Source

I have a project containing a xaml ResourceDictionary that I wish to use outside of a FrameworkElement. The resource dictionary will contain a DataTemplate for a class local to the project to avoid polluting the app.xaml (as the project is a prism module, and will not always be present depending on config).
So, I have a test.xaml file with a Resource build action.
This is intended to supply the DataTemplate for a TestObject class.
In the TestObject class I have a GetTemplate() method
The following works:
DataTemplate GetTemplate()
{
Uri uri = new Uri("MyProject;component/test.xaml", UriKind.Relative);
var dict = new ResourceDictionary { Source = uri};
return (DataTemplate)dict["TestObjectDataTemplate"];
}
This throws an exception when I assign the uri to the ResourceDictionary.Source property
DataTemplate GetTemplate()
{
Uri uri = new Uri("/test.xaml", UriKind.Relative);
var dict = new ResourceDictionary { Source = uri};
return (DataTemplate)dict["TestObjectDataTemplate"];
}
The second example fails as the /test.xaml can't be found in the local assembly. Why would I need to access it with "ReferencedAssembly;component/test.xaml" ?
In this instance, does local assembly mean the executing assembly or the assembly the code/resource is part of?
Edit: Updated to reflect the actual issue.
Try UriKind.RelativeOrAbsolute.
More clearly like.
DataTemplate GetTemplate()
{
ResourceDictionary resource = new ResourceDictionary()
{
Source = new Uri(#"/AssemblyFullName;component/test.xaml", UriKind.RelativeOrAbsolute)
};
return (DataTemplate)resource["TestObjectDataTemplate"];
}
Edit:
In this instance, does local assembly
mean the executing assembly or the
assembly the code/resource is part of?
Say for example:
You have two projects Project A and Project B.
You are using Project A as reference in Project B
Now, if you want to use the resource like this /test.xaml. Then, this resource should reside in the Project B. Since, it is the executing assembly. [It will be available for both Project A as well as Project B. You could use the above mentioned syntax. like /test.xaml]
If you want the resource to be defined and used inside Project A. Then, you should use "/ProjectA;component/test.xaml" because it is not the current executing assembly. [It will be available for both Project A as well as Project B. You have to use "/ProjectA;component/test.xaml" this to access in both the projects]
Setting the Source attr works, I successfully used it in many projects.
Your Uri might be wrong. You should try a fully qualified pack Uri, like :
dict.Source = new Uri("pack://application:,,,/test.xaml");
If your test.xaml file is not in the project root, be sure to set its path correctly.

Resources