Making Silverlight 2 programs work in Silverlight 4 - silverlight

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?

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.

Silverlight App object Does not exist' Error

name 'App' does not exist in the current context.
How that possible?
Have to note my initialization code is different than MainPage() type, as I converted SketchFlow app into production Silverlight. They instruct you to do init code via System.Windows.Controls.Frame():
private void Application_Startup(object sender, StartupEventArgs e)
{
this.RootVisual = new System.Windows.Controls.Frame() { Source = new Uri("/MyAppScreen.xaml", UriKind.Relative) };
}
public static string ValueFromHome =
"A Value on Home page";
the goal was to set up public var inside App object so I can access it from various screens down the road
Accessing Resource data requires calling App object I believe as in below, is that correct? so this won't help me
string color = App.Current.Resources["customColor"].ToString();
If you are just storing strings, look into using Resource files. Then they can be translated if that ever becomes necessary.
EDIT (to explain the resource file usage): To access the resource, first create a .resx file in your project (let's say you name it MainResource.resx), change the access modifier drop down to public, add your string with Name: ValueFromHome and Value: "A Value on Home page".
Then you can get the value by adding a using to the namespace of the resource if needed and calling it directly like so:
string value = MainResource.ValueFromHome;
I'd be wary of static variables hanging around. Maybe you could use a MainViewModel to store that value. If you really need a static variable create a new static class in your project and put your ValueFromHome property in that class. The App probably isn't available since it is a Silverlight construct and not made to be available to all areas.

Error Application cast in WPF

i have 2 projects in my solution (main is A.WPF and secondary is B.WPF)
when i'm trying to access variables inside my App.xaml.cs in B.WPF:
filename = ((App)Application.Current).ErrorLogFileName;
i get the following error:
Unable to cast object of type 'A.App' to type 'B.App'.
i also tried the following:
filename = ((B.App)Application.Current).ErrorLogFileName;
but still the same error...
the definition in B.App is:
private string _errorLogFileName = "error log.xml";
public string ErrorLogFileName
{
get { return _errorLogFileName; }
}
please assist...
Looks like you need to do:
filename = ((A.App)Application.Current).ErrorLogFileName;
The error is saying the type is A.App, yet in both cases you are trying to cast to B.App.
There can only be one current application also.
Application.Current refers to the current application. The only way to be allowed to cast the current App to another App-type is when the other App-type is a base class of the current App-type.
Are A.App and B.App siblings or is B.App a base class of A.App?
If you don't want B to have a reference to A (or can't as you want A to reference B and that would cause a circular reference), then you need a common type defined in a third assembly that both A and B reference. In our implementation we tend to have a ConfigurationData type that is in a separate project referenced by both Wpf projects, e.g.
public static class ConfigurationData
{
private static string _errorLogFileName = "error log.xml";
public string ErrorLogFileName
{
get { return _errorLogFileName; }
}
}
Another approach would be to define an Interface for your ErrorLogFileName property in a 3rd assembly that both A and B reference, and then implement that interface on your Wpf Application class - A and B would then both be able to cast to that type. If you wanted your A project to set the values on that at runtime, you could make the ErrorLogFileName a read-write property instead and initialize it in your application startup.
I personally prefer using a separate ConfigurationData type from the Wpf app object for this kind of stuff (ErrorLogFileName etc.) as it can then also be used for code that might execute in a unit test and therefore might not be running under a Wpf application - it also avoids having to do casts all over the place (ConfigurationData.ErrorLogFileName instead of ((IAppConfigurationData)Application.Current).ErrorLogFileName.
BTW, if you have an Application object in both assemblies it sounds like you might have both assemblies configured to build as Output type: Windows Application in your project properties. You should only really have one assembly that is configured as the Windows Application and the rest should be Class Library to avoid confusing numbers of Application classes being generated - only the one in the main EXE (and it's related resources) will get created at runtime.

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.

Silverlight 2 ArgumentException

I have a silverlight 2 app that has an ObservableCollection of a class from a separate assem/lib. When I set my ListBox.ItemsSource on that collection, and run it, I get the error code:
4004 "System.ArgumentException: Value does not fall within the expected range."
Here is part of the code:
public partial class Page : UserControl
{
ObservableCollection<Some.Lib.Owner> ooc;
public Page()
{
ooc = new ObservableCollection<Some.Lib.Owner>();
Some.Lib.Owner o1 = new Some.Lib.Owner() { FirstName = "test1" };
Some.Lib.Owner o2 = new Some.Lib.Owner() { FirstName = "test2" };
Some.Lib.Owner o3 = new Some.Lib.Owner() { FirstName = "test3" };
ooc.Add(o1);
ooc.Add(o2);
ooc.Add(o3);
InitializeComponent();
lb1.ItemsSource = ooc;
}
}
But when I create the Owner class within this same project, everything works fine.
Is there some security things going on behind the scenes? Also, I'm using the generate a html page option and not the aspx option, when I created this Silverlight 2 app.
Are you trying to use a standard class library or a "Silverlight Class Library"?
Because Silverlight 2 uses a subset of the CLR it cannot access standard class libraries that were compiled using the full CLR. To use an external assembly you must create it as a "Silverlight Class Library". This will create a project that only includes the namespaces available to Silverlight and will allow you to reference the assembly within your Silverlight project.
Check out the MSDN article ".NET Framework Class Library for Silverlight" for more info.
It may be because you're not handling a failure in SubmittedChanges(). See http://www.scottleckie.com/2010/04/code-4004-unhandled-error-in-silverlight-application/ for more info
Everything is in one project now.
Yes, but not like you just did it, instead, share, link to the file(s).
For this an old jedi mind trick of Silverlight when there is a need to share common entity code between the app and the service. This is done when the library could not be brought in due to the differences in .Net/CLR.
The trick is to include the file as a link into the other project. Here is how
In the target (Silverlight project) folder which needs the code file, right click and select Add then Existing Item... or shift alt A.
Browse to the location of the origins file(s) found and select the/those file(s).
Once the item(s) have been selected, then on the Add button select the drop down arrow.
Select Add as link to add the file(s) as a link into the folder.
Once done, there is only one copy, but built in two different places.
That will give access to the file as if the file was actually within the project's folder, but the file physically resides elsewhere...and avoids CLR issues.

Resources