How to update Target object from markup extension in SL5? - silverlight-5.0

I'm trying this code in a markup extension in Silverlight 5.
public override object ProvideValue(IServiceProvider serviceProvider)
{
_target = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
_depObj = _target.TargetObject as DependencyObject;
_depProp = _target.TargetProperty as DependencyProperty;
return GetText(TextId, DefaultText);
}
depObj seems to be provided correctly, however depProp seems not to be of type
DependencyProperty (The type is Sytem.String (of System.Reflection.PropertyInfo)). The cast results in null.
depProp is representing to the right Text or Content property, but without it being a
DependencyProperty I cannot set its value.
Any input greatly appreciated.
SiKo

Not sure why its coming up as a PropertyInfo but you can of course set the value with code something like:
if (TargetProperty is DependencyProperty)
{
var dependencyObject = target as DependencyObject;
if (dependencyObject != null)
{
var newValue = GetValue();
dependencyObject.SetValue(TargetProperty as DependencyProperty, newValue);
}
}
else if (TargetProperty is PropertyInfo)
{
var pi = target as PropertyInfo;
pi.SetValue(target, GetValue(), null);
}

The approach #Berryl gave above could work. But if you also need to get to the DependencyProperty, you can use something like this. This code also demonstrates the subtle differences between silverlight and WPF, but both can work great.
For silverlight or WPF only, you can remove the parts before or after the #else to simplify the code a little bit.
But the part that resolves the dependency property is in the middle (assigning _property).
public override object ProvideValue(IServiceProvider serviceProvider)
{
IProvideValueTarget Target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
if (Target == null) {
throw new InvalidOperationException(
"Cannot resolve the IProvideValueTarget. Are you binding to a property?");
}
/* we need the dependency property (for bindings) */
#if SILVERLIGHT
PropertyInfo Property = (PropertyInfo)Target.TargetProperty;
/* resolve the dependency property */
FieldInfo DepPropertyInfo = Target.TargetObject.GetType()
.GetField(Property.Name + "Property", BindingFlags.Static | BindingFlags.Public);
_property = (DependencyProperty)DepPropertyInfo.GetValue(/* obj = */ null);
#else
_property = Target.TargetProperty as DependencyProperty;
#endif
if (_property != null) {
#if SILVERLIGHT
if (Property.Name.StartsWith("Text")) {
UpdateSourceTrigger = UpdateSourceTrigger.Default;
#else
if (_property.Name.StartsWith("Text")) {
UpdateSourceTrigger = UpdateSourceTrigger.LostFocus;
#endif
}
else {
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
}
}

Related

EMF: Defining a generic containment reference in an Ecore metamodel

It is a long time since I have used EMF and I am stuck on this.
I would like to create a generic type equivalent to:
class Result<T:ASTNode>{
T root;
}
I am defining this in Kotlin:
val result = ePackage.createEClass("Result").apply {
// I think this part is correct
val typeParameter = EcoreFactory.eINSTANCE.createETypeParameter().apply {
this.name = "T"
this.eBounds.add(EcoreFactory.eINSTANCE.createEGenericType().apply {
// astNode is my EClass
this.eClassifier = astNode
})
}
this.eTypeParameters.add(typeParameter)
val rootContainment = EcoreFactory.eINSTANCE.createEReference()
rootContainment.name = "root"
// STUCK!
// here should I set rootContainment.eType? rootContainment.eGenericType?
// how?
rootContainment.isContainment = true
rootContainment.lowerBound = 0
rootContainment.upperBound = 1
this.eStructuralFeatures.add(rootContainment)
addContainment("issues", issue, 0, -1)
}
The equivalent .ecore is :
<eClassifiers xsi:type="ecore:EClass" name="Result">
<eTypeParameters name="T">
<eBounds eClassifier="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
</eTypeParameters>
<eStructuralFeatures xsi:type="ecore:EReference" name="t">
<eGenericType eTypeParameter="#//Result/T"/>
</eStructuralFeatures>
so you want to use rootContainment.eGenericType with a new EGenericType that references your ETypeParameter

How do I get a list of Startup Projects in Visual Studio?

It is possible to start a debug session including multiple assemblies. While the dialog is simple to use for setup, it can be difficult to see at a glance which projects are selected without scrolling through the whole lot.
Is it possible to see only the projects that are set to start?
Don't mind if this is via Visual Studio itself or inspecting some sort of file or other.
You can show a list of startup projects with the following command for Visual Commander (Language: C#):
public class C : VisualCommanderExt.ICommand
{
public void Run(EnvDTE80.DTE2 DTE, Microsoft.VisualStudio.Shell.Package package)
{
System.Windows.MessageBox.Show(string.Join(System.Environment.NewLine, GetStartupProjects(DTE).ToArray()));
}
System.Collections.Generic.List<string> GetStartupProjects(EnvDTE80.DTE2 dte)
{
if (dte != null && dte.Solution != null && dte.Solution.SolutionBuild != null)
{
System.Collections.Generic.List<string> result = new System.Collections.Generic.List<string>();
System.Array projects = dte.Solution.SolutionBuild.StartupProjects as System.Array;
if (projects != null)
{
foreach (string s in projects)
result.Add(s);
}
return result;
}
return null;
}
}
If you just want the project names themselves without the (potentially) lengthy path names:
using System.Linq;
public class C : VisualCommanderExt.ICommand
{
public void Run(EnvDTE80.DTE2 DTE, Microsoft.VisualStudio.Shell.Package package)
{
System.Windows.MessageBox.Show(string.Join(System.Environment.NewLine, GetStartupProjects(DTE).ToArray()));
}
System.Collections.Generic.List<string> GetStartupProjects(EnvDTE80.DTE2 dte)
{
if (dte == null || dte.Solution == null || dte.Solution.SolutionBuild == null) return null;
var result = new System.Collections.Generic.List<string>();
var projects = dte.Solution.SolutionBuild.StartupProjects as System.Array;
if (projects == null) return result;
result.AddRange(from string s in projects select s.Split('\\') into parts select parts[parts.Length - 1]);
return result;
}
}

Why is this Haxe try-catch block still crashing, when using Release mode for C++ target

I have a HaxeFlixel project, that is working OK in Debug mode for misc targets, including flash, neko and windows. But Targeting Windows in Release mode, I'm having an unexpected crash, and surprisingly it's happening inside a try-catch block. Here's the crashing function:
/**
* Will safely scan a parent node's children, search for a child by name, and return it's text.
* #param parent an Fast object that is parent of the `nodeNamed` node
* #param nodeName the node's name or a comma-separated path to the child (will scan recursively)
* #return node's text as String, or null if child is not there
*/
public static function getNodeText(parent:Fast, nodeName:String):String {
try {
var _node : Fast = getNodeNamed(parent, nodeName);
//if (_node == null)
// return null;
// next line will crash if _node is null
var it :Iterator<Xml> = _node.x.iterator();
if ( it == null || !it.hasNext() )
return null;
var v = it.next();
var n = it.next();
if( n != null ) {
if( v.nodeType == Xml.PCData && n.nodeType == Xml.CData && StringTools.trim(v.nodeValue) == "" ) {
var n2 = it.next();
if( n2 == null || (n2.nodeType == Xml.PCData && StringTools.trim(n2.nodeValue) == "" && it.next() == null) )
return n.nodeValue;
}
//does not only have data (has children)
return null;
}
if( v.nodeType != Xml.PCData && v.nodeType != Xml.CData )
//does not have data";
return null;
return v.nodeValue;
}catch (err:Dynamic) {
trace("Failed parsing node Text [" + nodeName+"] " + err );
return null;
}
}
By enabling if (_node == null) return null; line, It's working safely again. By catching errors as Dynamic I thought I was supposed to catch every possible error type! Why is this happening? And why is it appearing in release mode?
My IDE is FlashDevelop, and I'm using HaxeFlixel 3.3.6, lime 0.9.7 and openFL 1.4.0, if that makes any difference
EDIT: I suspect this has to do with how the translated C++ code missed the Dynamic Exception. The equivalent generated C++ code is:
STATIC_HX_DEFINE_DYNAMIC_FUNC2(BaxXML_obj,_getNodeNamed,return )
::String BaxXML_obj::getNodeText( ::haxe::xml::Fast parent,::String nodeName){
HX_STACK_FRAME("bax.utils.BaxXML","getNodeText",0x4a152f07,"bax.utils.BaxXML.getNodeText","bax/utils/BaxXML.hx",56,0xf6e2d3cc)
HX_STACK_ARG(parent,"parent")
HX_STACK_ARG(nodeName,"nodeName")
HX_STACK_LINE(56)
try
{
HX_STACK_CATCHABLE(Dynamic, 0);
{
HX_STACK_LINE(57)
::haxe::xml::Fast _node = ::bax::utils::BaxXML_obj::getNodeNamed(parent,nodeName); HX_STACK_VAR(_node,"_node");
HX_STACK_LINE(63)
Dynamic it = _node->x->iterator(); HX_STACK_VAR(it,"it");
// ... Let's skip the irrelevant code
}
catch(Dynamic __e){
{
HX_STACK_BEGIN_CATCH
Dynamic err = __e;{
HX_STACK_LINE(82)
::String _g5 = ::Std_obj::string(err); HX_STACK_VAR(_g5,"_g5");
HX_STACK_LINE(82)
::String _g6 = (((HX_CSTRING("Failed parsing node Text [") + nodeName) + HX_CSTRING("] ")) + _g5); HX_STACK_VAR(_g6,"_g6");
HX_STACK_LINE(82)
::haxe::Log_obj::trace(_g6,hx::SourceInfo(HX_CSTRING("BaxXML.hx"),82,HX_CSTRING("bax.utils.BaxXML"),HX_CSTRING("getNodeText")));
HX_STACK_LINE(83)
return null();
}
}
}
HX_STACK_LINE(56)
return null();
}
What haxedefs do you have defined?
Adding these to your project.xml might help:
<haxedef name="HXCPP_CHECK_POINTER"/> <!--makes null references cause errors-->
<haxedef name="HXCPP_STACK_LINE" /> <!--if you want line numbers-->
<haxedef name="HXCPP_STACK_TRACE"/> <!--if you want stack traces-->
You might also try the crashdumper library:
https://github.com/larsiusprime/crashdumper
(Crashdumper will turn on HXCPP_CHECK_POINTER by default as part of it's include.xml, and will set up hooks for both hxcpp's errors and openfl/lime's uncaught error events)
I guess this boils down to how C++ handles null-pointer Exceptions. It doesn't!
More info here or here
That seems odd, some questions that may help solving it.
It looks like you are doing quite some assumptions on how the xml looks (doing some manual it.next()), why is that?
Why are you using this big-ass try-catch block?
How does getNodeNamed look, it seems it can return null.
Do you have an example xml to test with?

Convert a string into closure in ColdFusion

I have a very basic question. Is it possible to convert a string into a closure? I tried evaluate() but it didn't work.
evaluate( "myFunction = function(val){ return dollarFormat( val ); }" );
What I have in mind is to save custom functions in the database as string and then run it as needed.
Thank you!
Edit: Just to clarify: I want to be able to save "function(val){ return dollarFormat( val ); }" as a string in database and be able to convert it into a functioning closure.
I would go with user2943775 answer:
<cfscript>
FileWrite("/ram/UDFs.cfm", "<cfset myFunction = function(val){ return dollarFormat( val ); }>")
include template="/ram/UDFs.cfm";
writedump(myFunction(10));
</cfscript>
And in your Application.cfc
component {
this.mappings["/ram"] = "ram://";
...
}
I came across a similar solution, though I was unable to use the in-memory filesystem due to security restrictions. In my Application.cfc, I added the following mapping:
this.mappings = {
"/models" = "#APP_ROOT_PATH#cfcs/models",
"/utils" = "#APP_ROOT_PATH#cfcs/utils",
"/modules" = "#APP_ROOT_PATH#_modules",
"/components" = "#APP_ROOT_PATH#cfcs",
"/udfs" = "#APP_ROOT_PATH#includes/udfs" // path for global (and temporary) UDFs
};
The UDF I created is as follows:
/**
* Takes a string representation of a function and returns it as a Closure
* #output false
* #return Closure
*/
private any function toClosure (required string closure) {
local.id = replace(createUUID(), "-", "", "all");
local.udfpath = "/udfs/udf#id#.cfm";
local.script = "<cfscript>local.fn#id# = #closure#;</cfscript>";
try {
fileWrite(expandPath(udfPath), script);
include udfpath;
} catch (any e) {
} finally {
try {
fileDelete(expandPath(udfPath));
} catch (any e) {}
}
if (!structkeyExists(local, "fn#id#") || !isClosure(local["fn#id#"])) {
throw (message="Unable to compile closure");
}
// return the closure
return local["fn#id#"];
}
And the result:
myFn = toClosure("function (num) { return num + 1; }");
myFn(1); // returns 2

Weka XRFFSaver including missing sparse values

I'm using the XRFFSaver class in the current weka dev version. I'm using xrff rather than arff as I have extremely sparse data and the specs here indicate that sparse instances are handled nicely and efficiently (i.e. not included in output).
However using XRFFSaver they are included in the output like this:
<value index="1" missing="yes"/>
<value index="2" missing="yes"/>
...
Which defeats the purpose of the whole exercise. Anyone know if this is operator error or will I need to write my own saver?
I had a quick look at the source and I could not find any way of toggling this behaviour in either XRFFSaver or XMLInstances, however it was a quick look.
tnx
I quickly hacked up a solution to this:
Note: This is in C# (I use weka through ikvm). However, this should be very simple for anyone to convert to Java.
Note2: The only important line is this one: if (sparse) continue which I also highlighted below with comments. Everything else is a straight copy of the weka source which I found through grepcode and google. Not even sure if its the latest version I copied so please use with discretion.
I also tested to ensure that the standard XRFFLoader handles this correctly and it appears it does.
Tnx
// Usage
var saver = new EfficientXRFFSaver();
saver.setCompressOutput(file.EndsWith(".gz"));
saver.setInstances(Instances);
saver.setFile(new java.io.File(file));
saver.writeBatch();
// Implementation
public class EfficientXRFFSaver : XRFFSaver
{
public override void resetOptions() {
base.resetOptions();
setFileExtension(getCompressOutput() ? XRFFLoader.FILE_EXTENSION_COMPRESSED : XRFFLoader.FILE_EXTENSION);
try { m_XMLInstances = new EfficientXMLInstances(); }
catch { m_XMLInstances = null; }
}
}
public class EfficientXMLInstances : XMLInstances
{
protected override void addInstance(Element parent, Instance inst) {
var node = m_Document.createElement(TAG_INSTANCE);
parent.appendChild(node);
var sparse = inst is SparseInstance;
if (sparse) { node.setAttribute(ATT_TYPE, VAL_SPARSE); }
if (inst.weight() != 1.0) { node.setAttribute(ATT_WEIGHT, Utils.doubleToString(inst.weight(), m_Precision)); }
for (var i = 0; i < inst.numValues(); i++) {
var index = inst.index(i);
var value = m_Document.createElement(TAG_VALUE);
if (inst.isMissing(index)) {
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// !!!!!!!!!! IMPORTANT !!!!!!!!!!!!!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// This line will not add this element if its missing and sparse.
if (sparse) continue;
value.setAttribute(ATT_MISSING, VAL_YES);
} else {
if (inst.attribute(index).isRelationValued()) {
var child = m_Document.createElement(TAG_INSTANCES);
value.appendChild(child);
for (var n = 0; n < inst.relationalValue(i).numInstances(); n++) {
addInstance(child, inst.relationalValue(i).instance(n));
}
} else {
value.appendChild(inst.attribute(index).type() == weka.core.Attribute.NUMERIC ?
m_Document.createTextNode(Utils.doubleToString(inst.value(index), m_Precision)) :
m_Document.createTextNode(validContent(inst.stringValue(index))));
}
}
node.appendChild(value);
if (sparse) { value.setAttribute(ATT_INDEX, "" + (index + 1)); }
}
}
}