Binding custom dependency property gets databinding to string cannot convert exception - windows-phone-8

I need to set the Xaml property of a RichTextBox user control via a binding expression in Windows Phone 8, and I found that it is not a DP, so I have decided to inherit from a RichTextBox and add a DP that will change the Xaml property with PropertyChanged event, anyways the code looks like this, stripped out irrelevant parts.
public class RichTextBoxWithBindableXaml : RichTextBox
{
public string BindableXaml
{
get { return (string)GetValue(BindableXamlProperty); }
set { SetValue(BindableXamlProperty, value); }
}
public static readonly DependencyProperty BindableXamlProperty =
DependencyProperty.Register("BindableXaml",
typeof(string),
typeof(RichTextBoxWithBindableXaml),
new PropertyMetadata(0));
}
//xaml code
<local:RichTextBoxWithBindableXaml BindableXaml="{Binding PageContent , Mode=OneWay}"> </local:RichTextBoxWithBindableXaml>
And I get the following dreaded exception message:
Object of type 'System.Windows.Data.Binding' cannot be converted to type 'System.String'.
I have checked many solutions to these exceptions and similar problems with data binding, and still going through the suggested similar questions on the right, and still cannot see why a simple thing wont work for me. The code I listed above is just the simplest implementations of a DP with a binding expression. Btw, the source PageContent is from a INotifyPropertyChanged object, and it works, I know because, it can bind to TextBlock's Text property.
Am I missing out something so obvious? I wouldn't want to post question for such a straightforward thing, but I cant seem to solve in any way.
EDIT:
Following P.S note turned out to be completely irrelevant.
P.S. My final doubt was on the way xmlns namespace local is loaded. It is loaded as clr assembly, could xaml parser think my custom inherited class as clr-only and confuse since clr properties are not dependency properties. Hope it doesnt sound stupid, i'm desperate. It is as such :
xmlns:local="clr-namespace:RumCli"

I found out that I should either provide a null PropertyMetadata (new PropertyMetadata(null) instead of 0), or a metadata with a default value type if the DP is supposed to be used in Xaml. For my sceneario, since I will make use of the PropertyChangedCallback, the propertymetadata that will passed to the Register method looks like this.
new PropertyMetadata(default(string), new PropertyChangedCallback(OnBindableXamlChanged))
hope, it helps to others.

For each dependency property one must supply a non subscribed value (not a C# term here) which suites the type of object which the consumer will access.
To quote MSDN Dependency Property Metadata
Dependency property metadata exists as an object that can be queried to examine the characteristics of a dependency property.
So for the value type results, a default for the different value types, such as a double is to use double.NaN. A decimal use decimal.Zero. While a string, string.empty is good as a base.
That allows whatever operation which may blindly reflect off of the property, it can determine what its true property type is and access it accordingly.
So assigning 0 to a string makes no sense in identifying that the property is a string which 0 identifies it as an integer. So the int as string is setting up a future runtime failures when objects try to assign bindings, styles and other items to it.

Related

Dart objects with strong typing from JSON

I'm learning Dart and was reading the article Using Dart with JSON Web Services, which told me that I could get help with type checking when converting my objects to and from JSON. I used their code snippet but ended up with compiler warnings. I found another Stack Overflow question which discussed the same problem, and the answer was to use the #proxy annotation and implement noSuchMethod. Here's my attempt:
abstract class Language {
String language;
List targets;
Map website;
}
#proxy
class LanguageImpl extends JsonObject implements Language {
LanguageImpl();
factory LanguageImpl.fromJsonString(string) {
return new JsonObject.fromJsonString(string, new LanguageImpl());
}
noSuchMethod(i) => super.noSuchMethod(i);
}
I don't know if the noSuchMethod implementation is correct, and #proxy seems redundant now. Regardless, the code doesn't do what I want. If I run
var lang1 = new LanguageImpl.fromJsonString('{"language":"Dart"}');
print(JSON.encode(lang1));
print(lang1.language);
print(lang1.language + "!");
var lang2 = new LanguageImpl.fromJsonString('{"language":13.37000}');
print(JSON.encode(lang2));
print(lang2.language);
print(lang2.language + "!");
I get the output
{"language":"Dart"}
Dart
Dart!
{"language":13.37}
13.37
type 'String' is not a subtype of type 'num' of 'other'.
and then a stacktrace. Hence, although the readability is a little bit better (one of the goals of the article), the strong typing promised by the article doesn't work and the code might or might not crash, depending on the input.
What am I doing wrong?
The article mentions static types in one paragraph but JsonObject has nothing to do with static types.
What you get from JsonObject is that you don't need Map access syntax.
Instead of someMap['language'] = value; you can write someObj.language = value; and you get the fields in the autocomplete list, but Dart is not able to do any type checking neither when you assign a value to a field of the object (someObj.language = value;) nor when you use fromJsonString() (as mentioned because of noSuchMethod/#proxy).
I assume that you want an exception to be thrown on this line:
var lang2 = new LanguageImpl.fromJsonString('{"language":13.37000}');
because 13.37 is not a String. In order for JsonObject to do this it would need to use mirrors to determine the type of the field and manually do a type check. This is possible, but it would add to the dart2js output size.
So barring that, I think that throwing a type error when reading the field is reasonable, and you might have just found a bug-worthy issue here. Since noSuchMethod is being used to implement an abstract method, the runtime can actually do a type check on the arguments and return values. It appears from your example that it's not. Care to file a bug?
If this was addressed, then JsonObject could immediate read a field after setting it to cause a type check when decoding without mirrors, and it could do that check in an assert() so that it's only done in checked mode. I think that would be a nice solution.

Why does this property/function name collision compile in AS3?

In ActionScript 3.0, this compiles:
public function set func(value:Function):void
{
}
public function func():void
{
}
This doesn't:
public function set someVar44(value:int):void
{
}
var someVar44:int;
Why does the first one compile? I suppose it's possible that Adobe just specifically and arbitrarily decided to block this for variables and to allow it for functions, but allowing it for either functions or variables doesn't seem to make any sense. I'm suspicious there's more to the story here. What am I not seeing?
This is really interesting, and took a fair amount of digging to get down to (although the answer seems painfully obvious).
As you know variables/properties cannot be declared in the same scope with identical names. Therefore the set function someVar44() and the variable someVar44 are in direct conflict (besides issues with trying to initialize the variable twice). Conversely if you had tried:
public function get func(value:Function):void
{
}
you would have ran into a similar issue with a duplicate function definition error. So why does the set function seem to allow you to get past these errors? As setters and getters are known for accessing and mutating properties of a class, it would seem they are also treated as class properties as opposed to a typical method, but this is not entirely the case. In fact, only the setter appears as a property of the public interface, the getter on the other hand is a method that can read like a property.
The setter:
public function set func(value:Function):void
Is read exactly like a property of the object, and without any other properties in direct conflict with it (i.e. - there is no current property like var func.) you do not receive a compiler error.
From adobe:
set Defines a setter, which is a method that appears in the public interface as a property.
get Defines a getter, which is a method that can be read like a property.
I believe that is why you are not getting a compiler error with set method. Although if you attempt to access that set method, the priority is immediately assumed to the function func(). That is, if you attempt this.func = function():void { } you will get the error:
Error #1037: Cannot assign to a method func
I can understand logically why the first compiles (in the older compiler). When considering an instance of the object, getting the obj.func property should return the member function you've defined, while setting the obj.func property should call the setter you've defined. This doesn't seem to be an ambiguity to me, though as we've seen, the runtime disagrees with me.
In the second case, you've defined a var (which defaults to the internal scope since you didn't say public, but that's another story) which, being externally visible, implicitly defines a getter and setter. So if someone sets the obj.someVar44 property of your object, are they calling the setter or setting your variable value? It's clearly an ambiguity and a duplicate definition.

Compatability when passing object to class

Ok, so this might be me being pendantic but I need to know the best way to do something:
(This is psudocode, not actual code. Actual code is huge)
I basically have in my package a class that goes like this:
internal class charsys extends DisplayObject {
Bunch of Variables
a few functions
}
I another class which I intend to add to the timeline I want to create a function like this:
public class charlist {
var list:Array = new Array();
var clock:Timer = new Timer(6000);
var temp:charsys;
function addObj(MC:DisplayObject, otherprops:int) {
temp=MC;
temp.props = otherprops;
list.push(temp)
}
function moveabout(e: event) {
stuff to move the items in list
}
function charlist() {
stuff to initialize the timers and handle them.
}
}
So the question is, is my method of populating this array a valid method of doing it, is there an easier way, can they inherit like this and do I even need to pass the objects like I am?
(Still writing the package, don't know if it works at all)
Yes, you can pass an object into a function, but you should be careful of what you are planning to do with that object inside that function. Say, if you are planning to pass only charsys objects, you write the function header as such:
function addObj(MC:charsys, otherprops:int) {
Note, the type is directly put into the function header. This way Flash compiler will be able to do many things.
First, it will query the function body for whether it refers to valid properties of a passed instance. Say, your charsys object does not have a props property, but has a prop property, this typing error will be immediately caught and reported. Also if that props is, for example, an int, and you are trying to assign a String value to it, you will again be notified.
Second, wherever you use that function, Flash compiler will statically check if an instance of correct type charsys is passed into the function, so if there is no charsys or its subclass, a compilation error is thrown.
And third, this helps YOU to learn how to provide correct types for functions, and not rely on dynamic classes like MovieClip, which can have a property of nearly any name assigned to anything, and this property's existence is not checked at compile time, possibly introducing nasty bugs with NaNs appearing from nowhere, or some elements not being displayed, etc.
About common usage of such methods - they can indeed be used to create/manage a group of similar objects of one class, to the extent of altering every possible property of them based on their corresponding values. While default values for properties are occasionally needed, these functions can be used to slightly (or not so slightly) alter them based on extra information. For example, I have a function that generates a ready-to-place TextField object, complete with formatting and altered default settings (multiline=true etc), which is then aligned and placed as I need it to be. You cannot alter default values in the TextField class, so you can use such a function to tailor a new text field object to your needs.
Hope this helps.
This would work, I think I would assign values to the properties of the charsys object before passing it into the add method though, rather than passing the properties and having a different class do the property assignment. If you have some common properties they could either have defaults in charsys class definition or you could set literals in the addObj method.

Actionscript 3 - passing custom class as parameter to custom class where parameter class not constructed

Hi and thanks in advance,
I have a custom class being constructed from my main class. In the custom class it has another custom class that is passed in as a parameter. I would like to strictly type the parameter variable but when I do, 'the type is not a compile type constant etc'.
This, I understand, is because the custom class used as a parameter has not yet been constructed.
It all works when I use the variable type ( * ) to type the parameter.
I suspect this is a design flaw, in that I am using an incorrect design pattern. It is actually hand-me-down code, having received a large project from someone else who is not entirely familiar with oop concepts and design patterns.
I have considered using a dummy constructor for the parametered class in my main class but the passed in class also takes a custom class (itself with a parametered constructor). I am considering using ... (rest) so that the custom classes' parameters are optional.
Is there any other way to control the order of construction of classes? Would the rest variables work?
Thanks
(edit)
in main.as within the constructor or another function
var parameter1:customclass2;
customclass1(parameter1);
in customclass1 constructor:
public function customclass1(parameter1:customclass2)
{
....
Flash complains that the compiled type cannot be found when I use the data type customclass 2 in the paramater. It does not complain when I use the variable data type * or leave out the data type (which then defaults to * anyway). I reason that this is because customclass2 has not yet been constructed and is therefore not available to the compiler.
Alternatively, I have not added the path of customclass2 to the compiler but I am fairly certain I have ruled this out.
There are over 10,000 lines of code and the whole thing works very well. I am rewriting simply to optimise for the compiler - strict data typing, error handling, etc. If I find a situation where inheritance etc is available as an option then I'll use it but it is already divided into classes (at least in the main part). It is simply for my own peace of mind and to maintain a policy of strict data typing so that compiler optimization works more efficiently.
thnx
I have not added the path of customclass2 to the compiler but I am fairly certain I have ruled this out.
So if you don't have the class written anywhere what can the compiler do ? It is going to choke of course. You either have to write the CustomClass class file or just use "thing:Object" or "thing:Asteriks". It's not going to complain when you use the "*" class type because it could be anything an array, string, a previously declared class. But when you specify something that doesn't exists it will just choke, regardless of the order the parameters are declared in.

Why do static Create methods exist?

I was wondering, why do static Create methods exist?
For instance, why use this code:
System.Xml.XmlReader reader = System.Xml.XmlReader.Create(inputUri);
over this code:
System.Xml.XmlReader reader = new System.Xml.XmlReader(inputUri);
I cannot find the rationale for using one over the other, and can't find any relation between classes who use this construct over the other.
Can anyone shed some light on this?
XmlReader is an abstract class. You cannot instantiate it.
Providing a Create method is an instance of the factory pattern. Depending on the specified arguments a different implementation of XmlReader is chosen and returned. For example, there are validating and non-validating XmlReader implementations in the .NET framework.
A more general answer...
The reason people like these kinds of methods, known as "static factory methods", is because you can give them a name (as opposed to constructors). So if you need three different constructors, you can instead create static factory methods which have names relevant to their use.
Another reason is that a factory method doesn't really need to create new objects - it can return the same one over and over if need be.
Because it can actually create and object of derived type that you have no access to or return an abstract class (as dtb answered). This is factory method pattern.
A constructor can only be used to create instances of one specific class, while a static Create method can create an instance of different classes depending on the input.
In the case of the XmlReader class the Create method will return an XmlDictionaryReader, XmlTextReader, XmlValidatingReader or XmlNodeReader, depending on which overload you use and what parameters you send to it.
This pattern allows the XmlReader class to provide you with instances of derived classes tailored to the parameters you passed to Create. Note in particular the overloads that accept an XmlReaderSettings object. A different XmlReader subclass can be returned to you depending on your settings.
A better example is WebRequest.Create(url). Depending on the URL you pass, you may receive an HttpWebRequest, an FtpWebRequest, etc.
Because you don't have to commit to the exact class of object you get. Constructors can only construct objects from exactly one class.
Because you can give the method a meaningful name, e.g. BigInt.probablePrime(). Constructors can only have the same name as the class.
Because you can have more than one factory method for the same parameter type combination, e.g. Point.fromPolarCoords(int, int) and Point.fromCartesianCoords(int, int), but there can be only one constructor Point(int, int).
(A much more detailed answer is given in Bloch's 'Effective Java'.)
Sometimes they exist as a form of self-documentation. I have a db access component that I can instantiate either with a connection string or the name of the connection in the config file. Both of these methods take strings as a parameter so they cannot be differentiated by arguments alone. So I created a FromConnectionString(string) factory method and a FromConnectionName(string) factory method. This nuance would entirely be lost by a new Foo(bool, string) line.
The idea is that this way they can change the implementation of XmlReader and not break any user code (e.g. they can change the actual type that is returned from the Create method).
I personally don't like this approach, because it creates an inverse relationship in the XmlReader class hierarchy. Maybe they thought that the Factory pattern is an overkill?
To encapsulate object creation.