I am trying to add a custom property to a base form that can be accessed via the Delphi property editor. If I simply add the property as I would with a standard component the property won't show up in the property editor. Here's what I tried:
unit TestForm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TfrmEasyIPBase = class(TForm)
private
FTest: String;
public
{ Public declarations }
published
property Test: String read FTest write FTest;
end;
var
frmEasyIPBase: TfrmEasyIPBase;
implementation
{$R *.dfm}
end.
Do I have to register the property at some point?
RegisterCustomModule should do the trick.
I don't have access to delphi right now but try adding your TForm descant to your project, add new form, edit the new form's pas file so it will look like
TMyNewForm = Class(TfrmEasyIPBase)
Also edit MyNewForm's DFM file - change object MyNewForm to inherit MyNewForm
Related
I would like to create interface with few properties but with a constructor rather than with pure text, something in this form:
const interfaceDeclaration = j.interfaceDeclaration(j.identifier("props"), /* ... */);
I have problem with ObjectTypeAnnotation and the last parameter
I want to create a custom label package but I don't really know how to do it.
I'm doing this:
File->New->Package
And then Add->New Component
I choose the ancester type, etc. finally click on Create New Component.
I got the following unit code.
unit MyLabel1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls;
type
TMyLabel1 = class(TLabel)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
published
{ Published declarations }
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Standard',[TMyLabel1]);
end;
end.
My Question is:
How can I set the font style like Color and Name in the code above?
When I select the custom label from the stardard pallet into a Form I want to have these properties already set.
I appreciate your help!
Thanks!
Take a look at TEnhancedPanel example in wiki.
I'm trying to create a TypeScript 1.0.2 (VS 2013 Update 2 RTM) definition file for the ASP.NET Ajax library, and I'm getting hung up on how to define the additional methods that MS Ajax adds to base JS types such as Array. I created a AspNetAjax.d.ts and a AspNetAjax-tests.ts file. When I attempt to use the "add" method in the test file, I get the compiler error that is listed below.
AspNetAjax.d.ts
interface Array<T> {
add(array: T[], item: T): void;
}
AspNetAjax-tests.ts
///<reference path="AspNetAjax.d.ts" />
var a: string[] = ['a', 'b', 'c', 'd'];
Array.add(a, 'e');
console.log(a.toString());
Error 1 The property 'add' does not exist on value of type '{ isArray(arg: any): boolean; prototype: any[]; (arrayLength?: number): any[]; (arrayLength: number): T[]; (...items: T[]): T[]; new(arrayLength?: number): any[]; new(arrayLength: number): T[]; new(...items: T[]): T[]; }'. c:\path\AspNetAjax-tests.ts 4 7 TypeScriptHTMLApp1
Other definitions from the same d.ts file are working in the tests file so I know that the reference is physically working. TypeScript also doesn't complain about the way I've declared the d.ts file (no red squiggles there).
I am aware of these other questions and I thought I was doing what they suggested, but it seems they're from late 2012/early 2013 so perhaps the way to do this has changed since then?
Extending Array in TypeScript
Adding a property to Array in Typescript
How can I add a static method to an existing type?
I need to code the d.ts so that the code in the .ts file will work. Any ideas?
The code you've written adds an add member to Array instances, not the built-in Array object.
The Array built-in object is defined in lib.d.ts near line 1134:
declare var Array: {
new (arrayLength?: number): any[];
new <T>(arrayLength: number): T[];
new <T>(...items: T[]): T[];
(arrayLength?: number): any[];
<T>(arrayLength: number): T[];
<T>(...items: T[]): T[];
isArray(arg: any): boolean;
prototype: Array<any>;
}
If you want to add a member to Array, you can modify the declaration as it appears in lib.d.ts.
If you're thinking that messing with lib.d.ts seems like a bad idea, it's because you shouldn't modify the built-in objects. There's no way to be sure that you and someone else haven't both decided that you have a great idea for an Array.add method that have completely different behavior.
You can take advantage of the declaration merging logic in TypeScript to extend Array as shown :
declare module Array{
export var add:Function;
}
var a: string[] = ['a', 'b', 'c', 'd'];
Array.add(a, 'e'); // Okay now
console.log(a.toString());
Between #basarat and #Ryan-Cavanaugh's answers I was able to come up with a minimally-horrible-to-the-user solution that works with TypeScript 1.0, as long as one is willing to accept that modifying the built-in JS objects is generally bad idea so it's OK if supporting that in TypeScript is slightly awkward.
Assuming that I am defining the ASP.NET AJAX extensions on the built-in JS Array object:
I will declare a module in the d.ts file called AspNetAjaxExtensions
I will create a non-exported interface inside that module declaration called JavaScriptArray<T>
I will create an exported interface inside that module declaration called Array<T> that extends JavaScriptArray<T>
I will copy all of the definitions for Array and Array<T> from the lib.d.ts that ships with TypeScript into the new JavaScriptArray<T> interface.
I can then proceed to model out only the extended functionality inside the new Array<T> interface.
This is somewhat anti-DRY for the d.ts author, but in reality these things very infrequently change and the stuff in JavaScriptArray<T> that was copied from lib.d.ts is self-contained. Technically, a build step could even be created to dynamically fill-in this interface.
For the user, they have to change their code that calls the extended Array object from this:
//will be an error in TypeScript 1.0
Array.add(x, 'thing');
to this:
//This works in TypeScript 1.0 after importing the above-described d.ts file.
(<AspNetAjaxExtensions.Array<string>>Array).add(x, 'thing');
Feasibly one could even Find+Replace Array.add( with (<AspNetAjaxExtensions.Array<any>>Array).add(.
They only need to do this whenever any of the extended methods on the built-in Array object are called (which will be called out by TypeScript syntax errors). Calls to normal Array methods will still use the "normal" definition in lib.d.ts.
Example new AspNetAjax.d.ts file:
declare module AspNetAjaxExtensions {
/** This interface definition was copied from lib.d.ts */
interface JavaScriptArray<T> {
new (arrayLength?: number): any[];
new <T>(arrayLength: number): T[];
/* -- Snip out many copied and pasted lines of code from lib.d.ts -- */
}
/** JavaScript Array object as extended by ASP.NET Ajax */
export interface Array<T> extends JavaScriptArray<T> {
/** Adds an element to the end of an Array object. This function is static and is invoked without creating an instance of the object.
http://msdn.microsoft.com/en-us/library/bb310854(v=vs.100).aspx
#param array The array to add the item to.
#param item The object to add to the array.
*/
add(array: T[], item: T): void;
/* -- etc... defining remaining extended methods -- */
}
}
In my Windows Phone app, I have a parent class file inherriting from UserControl, and multiple objects inheriting from that class. So the parent class, Parent.cs, is not partial.
Subclasses, are xaml objects, with xaml file and cs file.
I want to enable movements for all children, and am thus trying to achieve this in parent class.
Here is my code:
this.MoveObjectX = new DoubleAnimation();
this.MoveObjectY = new DoubleAnimation();
this.MoveObjectX.Duration = TimeSpan.FromMilliseconds(100);
this.MoveObjectY.Duration = TimeSpan.FromMilliseconds(100);
this.RenderTransform = new CompositeTransform();
Storyboard.SetTarget(this.MoveObjectX, this.RenderTransform);
Storyboard.SetTarget(this.MoveObjectY, this.RenderTransform);
Storyboard.SetTargetProperty(
this.MoveObjectX,
new PropertyPath(CompositeTransform.TranslateXProperty));
Storyboard.SetTargetProperty(
this.MoveObjectY,
new PropertyPath(CompositeTransform.TranslateYProperty));
this.storyboardMoveObject = new Storyboard();
this.storyboardMoveObject.Children.Add(this.MoveObjectX);
this.storyboardMoveObject.Children.Add(this.MoveObjectY);
this.storyboardMoveObject.Completed += new EventHandler(storyboardMoveObject_Completed);
But it does not work. Code complies and runs, but the children won't move.
I must add that in each child, I set the doubleanimations from and to numbers.
Thanks for your help.
If the code to do the movement is called from the constructor of the parent as you mention in the comments, you need to call the parent's constructor in the constructors of the children. It is not automatic, that is why your code never gets called for the children.
The easiest way to called the parent's constructor is to append base()
public child():base() { ... }
Alright got my own error: I was replacing RenderTransform with some other transform in sub classes. I just started to use a TransformGroup and everything works fine!
Thanks for your help
I'd like to change the representation of C# Doubles to rounded Int64 with a four decimal place shift in the serialization C# Driver's stack for MongoDB. In other words, store (Double)29.99 as (Int64)299900
I'd like this to be transparent to my app. I've had a look at custom serializers but I don't want to override everything and then switch on the Type with fallback to the default, as that's a bit messy.
I can see that RegisterSerializer() won't let me add one for an existing type, and that BsonDefaultSerializationProvider has a static list of primitive serializers and it's marked as internal with private members so I can't easily subclass.
I can also see that it's possible to RepresentAs Int64 for Doubles, but this is a cast not a conversion. I need essentially a cast AND a conversion in both serialization directions.
I wish I could just give the default serializer a custom serializer to override one of it's own, but that would mean a dirty hack.
Am I missing a really easy way?
You can definitely do this, you just have to get the timing right. When the driver starts up there are no serializers registered. When it needs a serializer, it looks it up in the dictionary where it keeps track of the serializers it knows about (i.e. the ones that have been registered). Only it it can't find one in the dictionary does it start figuring out where to get one (including calling the serialization providers) and if it finds one it registers it.
The limitation in RegisterSerializer is there so that you can't replace an existing serializer that has already been used. But that doesn't mean you can't register your own if you do it early enough.
However, keep in mind that registering a serializer is a global operation, so if you register a custom serializer for double it will be used for all doubles, which could lead to unexpected results!
Anyway, you could write the custom serializer something like this:
public class CustomDoubleSerializer : BsonBaseSerializer
{
public override object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
{
var rep = bsonReader.ReadInt64();
return rep / 100.0;
}
public override void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options)
{
var rep = (long)((double)value * 100);
bsonWriter.WriteInt64(rep);
}
}
And register it like this:
BsonSerializer.RegisterSerializer(typeof(double), new CustomDoubleSerializer());
You could test it using the following class:
public class C
{
public int Id;
public double X;
}
and this code:
BsonSerializer.RegisterSerializer(typeof(double), new CustomDoubleSerializer());
var c = new C { Id = 1, X = 29.99 };
var json = c.ToJson();
Console.WriteLine(json);
var r = BsonSerializer.Deserialize<C>(json);
Console.WriteLine(r.X);
You can also use your own serialization provider to tell Mongo which serializer to use for certain types, which I ended up doing to mitigate some of the timing issues mentioned when trying to override existing serializers. Here's an example of a serialisation provider that overrides how to serialize decimals:
public class CustomSerializationProvider : IBsonSerializationProvider
{
public IBsonSerializer GetSerializer(Type type)
{
if (type == typeof(decimal)) return new DecimalSerializer(BsonType.Decimal128);
return null; // falls back to Mongo defaults
}
}
If you return null from your custom serialization provider, it will fall back to using Mongo's default serialization provider.
Once you've written your provider, you just need to register it:
BsonSerializer.RegisterSerializationProvider(new CustomSerializationProvider());
I looked through the latest iteration of the driver's code and checked if there's some sort of backdoor to set custom serializers. I am afraid there's none; you should open an issue in the project's bug tracker if you think this needs to be looked at for future iterations of the driver (https://jira.mongodb.org/).
Personally, I'd open a ticket -- and if a quick workaround is necessary or required, I'd subclass DoubleSerializer, implement the new behavior, and then use Reflection to inject it into either MongoDB.Bson.Serialization.Serializers.DoubleSerializer.__instance or MongoDB.Bson.Serialization.BsonDefaultSerializationProvider.__serializers.