How do I create different sets of settings at run time? - wpf

My WPF application has a bunch of settings the user can adjust, I am using the built-in application settings (Properties.Settings... and a .settings file) to do this and it all works fine. Now, the application is supposed to allow the user to define different presets of settings for different purposes (different samples to be exact, it's a measurement system software) so they don't need to go over every setting again when they switch.
So, I would need to be able to create copies of the application settings at runtime and save them all separately in their own file, then restore them when the application starts up. I can create new settings files at design time but that's outside of the user's control and not what I am looking for. I also can create new Settings instances in code but when I save them it just overwrites the same user.config file the default instance used and the Save() method takes no arguments to save it somewhere else.
Any ideas?

You would have to create a separate class for your preset settings. Then you can save this as a list in Settings.
So lets say you have a preset class that holds your settings values:
public class Preset
{
public int MaxPower { get; set; }
public int AllowedRotations { get; set; }
}
You could in one place get all of these settings like so:
var presets = JsonConvert.DeserializeObject<List<Preset>>(Properties.Settings.Default.Presets);
And you would save the settings like so:
List<Preset> presets = null;
if (Properties.Settings.Default.Presets == null)
presets = new List<Preset>();
else
presets = JsonConvert.DeserializeObject<List<Preset>>(Properties.Settings.Default.Presets);
presets.Add(new Preset() { AllowedRotations = 1000, MaxPower = 200});
Properties.Settings.Default["Presets"] = JsonConvert.SerializeObject(presets);
Properties.Settings.Default.Save();
I guess you can also have some kind of unique ID for these objects so you can differentiate one preset from the other.
NOTE: I am using Json converter here and saving the list of objects as JSON.

Related

Orchard CMS connect external SQL Server

I'm planning to create some pages which display data from an external SQL Server with Orchard CMS. It looks like I need to write a new module to implement this function. Is there any example or idea to implement this requirement?
Yes, you will need to write a new module, which provides a new content part and a content part driver. That driver will be responsible for fetching the data from the external SQL Server, which you will set to a property on the shape you will be returning from your driver. The shape's view will then display your data.
This tutorial will walk you through writing a custom content part: http://docs.orchardproject.net/en/latest/Documentation/Writing-a-content-part/
When you do, make sure not to create the content part Record type, since you will not be storing and loading data from the Orchard database - you want to load data from an external database. These are the steps you should follow:
Create a new module
Create a content part class
Have your part inherit from ContentPart, not ContentPart<TRecord> since there won't be any "TRecord".
Create a content part driver
On the Display method, return a shape by calling the ContentShape method. Make sure to add the SQL data access logic within the lambda. If you do it outside of that lambda, that data access code will be invoked every time the content item using your content part is invoked. Although that sounds as if that is exactly what you want, there's a subtlety here that involves Placement.info, which you can use to determine when your shape will actually be rendered or not. If the placement logic determines that your shape should not be rendered, then you don't want to access your external data for nothing.
Create a Placement.info file to configure the shape's placement (within the context of the content item being rendered).
Create the Razor view for the shape that you return in step 3.2.
Create a Migrations class that will define your custom content part, and any content types to which you want to add your part to. See http://docs.orchardproject.net/en/latest/Documentation/Understanding-data-access/ for more information on how to create migrations.
PS. Instead of implementing your data access code directly in the driver, I recommend you implement that in a separate class. Because you know, separation of concerns and such. You can then inject that service into your driver. To have your service class be registered with the service container, make sure that you define an interface for it, that itself derives from IDependency.
Some sample pseudo code:
Service code:
public interface IMyExternalDataStore : IDependency {
IList<MyExternalDataRecord> GetMyData();
}
public class MyExternalDataStore : IMyExternalDataStore {
public IList<MyExternalDataRecord> GetMyData() {
// Connect to your SQL Server database, perhaps using EF, load the data and return it. Could of course also be simply a DataSet.
}
}
Content Part:
public class MyExternalDataPart : ContentPart {
// Nothing here, unless you want to include some properties here that influence the data that you want to load. If so, you'll also want to implement the Editor methods in your content part driver, but I'm keeping it simple.
}
Content Part Driver:
public class MyExternalDataPartDriver : ContentPartDriver<MyExternalContentPart> {
private readonly IMyExternalDataStore _dataStore;
public MyExternalDataPartDriver(IMyExternalDataStore dataStore) {
_dataStore = dataStore;
}
protected override DriverResult Display(SlideShowProPart part, string displayType, dynamic shapeHelper) {
return ContentShape("Parts_MyExternalData", () => {
// Notice that we're performing the data access here within the lambda (the so called "shape factory method").
var data = _dataStore.GetMyData();
// Notice that I'm creating a property called "MyData"on the shape (which is a dynamic object).
return shapeHelper.Parts_MyExternalData(MyData: data));
}
}
}
Razor view for the Parts_MyExternalData shape:
Filename: Parts.MyExternalData.cshtml
#{
var records = (IList<MyExternalDataRecord>)Model.MyData;
}
<ul>
#foreach(var record in records) {
<li>#record.ToString()</li>
}
</ul>
Placement.info:
<Placement>
<Place Parts_MyExternalData="Content:0"/>
</Placement>
Migrations:
public class Migrations : DataMigrationImpl {
public int Create() {
// Define your content part so that you can attach it to any content type from the UI.
ContentDefinitionManager.AlterPartDefinition("MyExternalDataPart", part => part.Attachable());
// Optionally, define a new content type here programmatically or attach it to an existing type.
return 1;
}
}

Handling Kinect in Main Window and passing this reference to UserControls

I have a project in WPF with a lot of UserControls, some user controls uses Kinect KinectColorViewer.xaml
I want to handle the sensor discovering and setup (conect, disconect, etc) in main window and serve it to my UserControls, how is the best way to do it?
Here is the project that explains my question.
If you prefer, here are the github link.
From your example code,
Assuming you want to maintain as much of the already available code from Microsoft, you will want to set up a reference to the KinectSensorManager on initializing your application. My constructor normally looks something like this:
private readonly KinectSensorChooser sensorChooser = new KinectSensorChooser();
public KinectSensorManager KinectSensorManager { get; private set; }
public MainViewModel()
{
// initialize the Kinect sensor manager
KinectSensorManager = new KinectSensorManager();
KinectSensorManager.KinectSensorChanged += this.KinectSensorChanged;
// locate an available sensor
sensorChooser.Start();
// bind chooser's sensor value to the local sensor manager
var kinectSensorBinding = new Binding("Kinect") { Source = this.sensorChooser };
BindingOperations.SetBinding(this.KinectSensorManager, KinectSensorManager.KinectSensorProperty, kinectSensorBinding);
}
The KinectSensorManager is just a helper class. You can rewrite code to easily avoid using it, but it doesn't do anything bad (does a lot of nice stuff for you) so I've just keep using it. Also, since I'm assuming you want to re-use as much code as possible, we want to maintain its usage.
For your control, you can extend KinectControl which will set up a bunch of helpful items for you. So...
public partial class KinectUserControl : KinectControl
{
...
}
This will give your control access to a lot of override-able functions that listen in to various events (like KinectSensorChanged). Check our the KinectColorViewer code and you can see how it overrides this function, which allows it to automatically start displaying new data if you swap Kinects.
When declaring your control in the XAML you can now add a reference to the KinectSensorManager:
<my:KinectUserControl KinectSensorManager="{Binding KinectSensorManager}" />
Because your control now has a KinectSensorManager property, it should pass through to your KinectColorViewer control as well.

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.

How can I write (Application.Current as App) in my Silverlight class library?

I have few public properties in App.xaml.cs which is in project A and I want to refer them in my project B. However my project A has a reference to project B, so I cannot add again the reference of project A in project B otherwise it will result in cyclic error. So how can I refer those properties in my class library? I don't want to use reflection :).
As a workaround I have stored those properties in one class in project B (so it can be referred in project A as well as project B) and made those properties to be static and all works fine. However I am still curious to know what if I had stored them in App.xaml.cs? Any options available?
Thanks in advance :)
The App class should expose things that are only relevant to the application project. As soon as you realised that you wanted these things accessable in B.dll they became relevant to more than just the application project and therefore no longer belong in the application project.
Adding a class to B.dll that carries these things as static properties could be a reasonable approach. Another common pattern is to have a single Current static property.
public MyClass
{
private static MyClass _current = new MyClass();
public static MyClass Current { get { return _current; } }
public string SomeInstanceValue { get; set; }
}
Both A and B would access things using the pattern var x = MyClass.Current.SomeInstanceValue. The advantage of this approach is that it allows the Current property getter to determine if a "current" instance is available or not.
You might also want to review the documentation on ApplicationLifeTimeObjects.
When A and B both need something, maybe you should put them in a C project (C as in Common) and then refer to C from both A and B.

How to adjust constraints / DB mapping for Map within grails domain class

Following grails domain class:
class MyClass {
Map myMap
}
Now for myMap, grails automatically creates a new table for the elements in the map. However if I add elements which are too long (e.g. 1024 characters), I get a DB error.
Can I somehow tell grails to make the respective column in myMap's table big enough to allow for larger Strings, or do I have to do this manually in the DB?
I already tried
static constraints = {
myMap(maxSize:1024)
}
which doesn't work (as expected because maxSize should refer to the Map's values and not to the Map itself).
If not via constraints, maybe there's a way to do it via
static mapping { ... }
?
An alternative approach I used successfully was to push the map out into a collection of a collaborator domain class.
class DynaProperty {
String name
String value
static belongsTo = MyClass
static constraints = {
value(maxSize:4000) //Or whatever number is appropriate
}
}
And then in MyClass:
class MyClass {
static hasMany = [dynaProperties:DynaProperty]
}
This is almost a map, and it gives you the ability to use dynamic finders to pull up an individual entry.
what are you trying to accomplish? Is there always the same number of things in the map? If there is you should define those properties on your class.
You can see the problem with your current approach -- there is no way to figure out what might be in the map until runtime, so how can grails possibly create a columns for it? Im surprised it even worked to begin with...

Resources