I want to derive Shape class following:
class MyRectangle : Shape
{
protected override System.Windows.Media.Geometry DefiningGeometry
{
get { return null; }
}
}
but I get error because DefiningGeometry property can't be overrided (althought wpf can).
How can i custom shape in WP8 ?
You should base your custom shape on a Path rather than inheriting from Shape directly.
Related
I got a Windows Runtime component authored in C++/CX that contains four dependency properties. Three of those properties set the color channels red, green and blue in the underlying renderer. The C++/C code for one such property looks as follows:
uint8_t DemoControl::Red::get()
{
return static_cast<uint8_t>(GetValue(RedProperty));
}
void DemoControl::Red::set(uint8_t r)
{
SetValue(RedProperty, r);
}
DependencyProperty^ DemoControl::_redProperty =
DependencyProperty::Register("Red",
uint_t::typeid,
DemoControl::typeid,
ref new PropertyMetadata(127, ref new PropertyChangedCallback(&DemoControl::OnRedChanged)));
void DemoControl::OnRedChanged(DependencyObject^ d, DependencyPropertyChangedEventArgs^ e)
{
DemoControl^ DemoControl = static_cast<DemoControl^>(d);
DemoControl->renderer->SetRed(static_cast<uint8_t>(e->NewValue));
}
The fourth property returns the entire color, i.e. it is a combination of the values of the three other properties.
The question is, how would I update that color property if either the red, green or blue property changes without triggering the code attached to the color property via data binding?
A similar question has been asked here but for WPF. The answer suggests to use value coercion but this seems to be a feature unavailable to Windows Runtime components. The PropertyMetadata object used when registering the dependency property does not support CoerceValueCallback from what I can see.
I'm not a C++ expert, but at least for your scenario, I think I can help.
You can register the same callback for multiple Dependency Properties. So in your specific case, you could just have a single OnColorComponentChanged callback:
void DemoControl::OnColorComponentChanged(DependencyObject^ d, DependencyPropertyChangedEventArgs^ e)
{
DemoControl^ DemoControl = static_cast<DemoControl^>(d);
if (e->Property == DemoControl::RedProperty) // Hand Wave Syntax Here
{
DemoControl->renderer->SetRed(static_cast<uint8_t>(e->NewValue));
}
else if (e->Property == DemoControl::GreenProperty)
{
DemoControl->renderer->SetGreen(static_cast<uint8_t>(e->NewValue));
}
else if (e->Property == DemoControl::BlueProperty)
{
DemoControl->renderer->SetBlue(static_cast<uint8_t>(e->NewValue));
}
// Hand Wave Here
DemoControl->Color = MakeColor(DemoControl->Red, DemoControl->Green, DemoControl->Blue);
}
I have a button as part of a Xamarin Forms custom renderer. I can style the button as I wish on iOS and Android in code without an issue and for the most part, can do the same on Windows Phone 8.
I'm having a problem though with including an image on a button with text next to it and altering the border on the button so it is rounded. I've found plenty of examples using XAML, but not in pure C#.
Currently, the custom renderer on Windows Phone looks like this
[assembly: ExportRenderer(typeof(NewButton), typeof(NewButtonRenderer))]
namespace WinPhone
{
class NewButtonRenderer : ButtonRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.ApplyTemplate();
var border = new Border
{
CornerRadius = new System.Windows.CornerRadius(10),
};
Control.Foreground = new SolidColorBrush(Colors.White);
Control.Background = new SolidColorBrush(System.Windows.Media.Color.FromArgb(255, 130, 186, 132));
Control.BorderBrush = new SolidColorBrush(System.Windows.Media.Color.FromArgb(255,45,176,51)) ;
Control.BorderThickness = new System.Windows.Thickness(0.8);
}
}
}
}
I have a Border set up, but can't find a way to add it (and secondary to this, if I have the background, border brush and border thickness in the Border object, does it have the same effect as applying directly to the control?), nor a way of creating an image button with an image in my Images directory.
Is what I'm trying to do correct or am I missing a piece of the jigsaw? I'm doing this in pure C# for a specific reason.
I'm very new on AS3. I would like to create a shape as i defined in my own constructor class.
It should create a shape when class was created. (Constructor)
I commented my want in following code :
ballShape class
public class ballShape {
public function ballShape() {
// define shape properties.
// create shape and put that in x = 0, y = 0
}
}
Any helps would be awesome.
You can easily do this while extending your class to Shape or Sprite
Here's your code
public class ballShape extends Sprite {
public function ballShape() {
// define shape properties. The graphics object is already added to your Sprite, no need to manually addChild() this object.
graphics.beginFill(color, alpha); // you can begin a fill with this method, there are also methods to start a bitmap fill, gradient fill.
graphics.drawRect( x, y, width, height ); // draw a shape
graphics.endFill();
}
}
While Shape can have the same functionality to draw shapes and lines, I chose Sprite, because:
You will have interactivity and be able to dispatch events from that class
You will have a set of useful properties that Sprite has.
For more info on the Graphics class, please refer to http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Graphics.html
Lets's say you have 2 classes ToolBar and DrawingToolBar. ToolBar is to serve as a base class for various other toolbars, for various tools. ToolBar handles the basic 'toolbar-y' stuff like opening, closing, dragging, dropping, etc. The DrawingToolBar adds functionality that is specific to a particular tool - tool-specific buttons, etc.
public class ToolBar extends Sprite {
public var closeBtn:Sprite
public function ToolBar():void {
addChild(closeBtn)
closeBtn.addEventListener(MouseEvent.CLICK, closeBtn_onClick)
}
protected function closeBtn_onClick(e:Event):void {
close()
}
public function open():void {
// blah
}
public function close():void {
// blah
}
}
and:
public class DrawingToolBar extends ToolBar{
public var penBtn: Sprite
public var paintbrushBtn: Sprite
public var colorPicker: ColorPicker
public function DrawingToolBar():void {
super()
}
public function getColour():int {
return colorPicker.color;
}
}
Now, we also have another 2 classes - Tool and DrawingTool. Again, Tool is a base class for various tools (incl. DrawingTool). If I make a ToolBar member in Tool (typed as ToolBar), we can delegate common tasks, eg. when the Tool is enabled, it adds the ToolBar to the stage, etc. The DrawingTool can instantiate the ToolBar as a DrawingToolBar so the correct library asset is used (but the instance is still typed as ToolBar).
public class Tool {
public var toolBar:ToolBar
public function Tool():void {
initToolBar()
}
protected function initToolBar():void {
addChild(toolBar)
}
}
and:
public class DrawingTool extends Tool {
public function DrawingTool():void {
super()
}
override protected function initToolBar():void {
toolbar = new DrawingToolBar() // this is probably very naughty
super.initToolBar()
}
public function getColor():int {
return toolBar.getColor() // this fails because toolBar is type as ToolBar not DrawingToolBar
}
}
The problem comes when, in DrawingTool I want to call a method of DrawingToolBar. Because the toolbar is typed as ToolBar, I can't call methods of DrawingToolBar on it. What do I do?
cast it every time I want to call a method of DrawingToolBar?
create a member in DrawingTool (eg. var drawingToolBar: DrawingToolBar), instantiate that and then make toolBar = drawingToolBar?
The first seems clunky, I don't even know if it would work. The second seems better but it feels a bit 'wrong'.
Is there another way? Or am I mis-using inheritance here?
You are probably mixing too many functionnalities into your toolbar. If you think MVC, you are missing a Model.
More precisely, the color picker should not be a property of your toolbar. The color picker is a property of your tool. Each drawing tool should be self contained and have its own color picker. If all drawing tools need to share the same color, you'll need a Drawing model that is shared by all drawing tools.
I would also change the relation between the Toolbar and its tools in the other direction. A toolbar has tools, but the tools themselves should be self contained and not have a reference to their containing toolbar.
The Java / Swing model is very clean on how it works with toolbars. You could get some inspiration from it : http://download.oracle.com/javase/tutorial/uiswing/components/toolbar.html
I have a png image on Library that i have declared it via Properties as Background class which extends BitmapData.
When i type:
var BMDClass:Class = getDefinitionByName( "Background" ) as Class;
i get: variable Background is not defined!!
But when i do:
trace( getQualifiedClassName( new Background(0,0) ) );
i get: Background !!
I can't figure out the cause of the error.
I believe this is because you need to have a reference to the Background class before you can actually get the definition by name. Simply importing the Background class will not compile the class in to your swf, you need to reference it in some way. Creating an instance of the class is one way, however you can also reference the class after your import.
try something like...
import com.somedomain.Background;
Background;
This should create a reference to you class and ensure it is compiled in to your swf.
Edit to show multiple class usage.
If you have multiple background classes, I would recommend trying to make them adhere to an interface. I would then also create a background factory class that would allow you to create background instances from your configuration file. This also means that you would be able to put all your references to your background classes in the factory class. Here is what the factory could look like.
// let the compiler know we need these background classes
import com.somedomain.backgrounds.*;
DarkBackground;
LightBackground;
ImageBackground;
class BackgroundFactory
{
public function create(type:String):Background
{
var bgClass:Class = getDefinitionByName(type) as Class;
return new bgClass();
}
}
Then to get a background instance from your config, you would do something like...
// parse your config file...not sure what format you've got it in.
// instantiate a background factory and create an instance based on the name from your config.
var bgFactory:BackgroundFactory = new BackgroundFactory();
var bg:Background = bgFactory.create(someStr);
Edit to extend example
package com.somedomain.background
{
interface Background
{
function get img():Bitmap;
}
}
package com.somedomain.background
{
class SomeImageBackground extends Sprite implements Background
{
protected var _img:Bitmap;
public function SomeImageBackground():void
{
_img = new SomeAssetFromLibrary();
}
public function get img():Bitmap
{
return _img;
}
}
}
Using these external classes would give you a bit more control over where the images come from. You could load them external, embed them using the embed meta data and even load them from the stage.