Extending the built in Windows Phone 8 Map control - windows-phone-8

For educational purposes, I want to extend the WP8 Map control to add a property for the current location (e.g so I can call myMap.CurrentLocation) and then use this custom control in my XAML template. Is this even possible?

If it wasn't sealed you could just inherit form it and add whatever other properties you want.
Unfortunately it is sealed so I'd suggest creating a new UserControl which includes a map instance and then add whatever other properties you want to that control. Make the new properties either regular ones or DependencyProperties as necessary you could also create wrapper properties to those of the map control or expose the inner control directly. It will depend on your specific use cases.

Related

Knockout Google Map: Component vs. Custom Binding Handler

When I google "Knockout Google Maps" I find quite some KO-based Google Maps implementations. All of which I was able to find take the approach to use a custom binding handler whereas I originally intended to implement it as a Knockout component.
Examples:
http://www.codeproject.com/Articles/351298/KnockoutJS-and-Google-Maps-binding
http://www.hoonzis.com/knockoutjs-and-google-maps-binding/
https://github.com/manuel-guilbault/knockout.google.maps
Can anyone point me in the right direction why one would prefer a custom binding handler over a KO component here?
My planned use case is this:
I'm implementing a page with a list of address search results. The list so far is a KO component, each list entry is generated by another KO component which the list component repeatedly calls in a foreach binding. Next to this list of search results I need a google map showing the result entries also in the map. There will also be quite a lot of interaction between the list, the list entries and the map.
Here's what I've got so far:
var GMap = function () {
var self = this;
var initMap = function() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 13,
center: {lat: 51.4387974, lng: 6.9922915}
});
};
initMap();
};
$(document).ready(function() {
ko.components.register('gmap', {
viewModel: GMap,
template: { element: 'gmap' }
});
ko.applyBindings();
});
#map {
height: 400px;
width: 600px;
}
<script src="https://maps.googleapis.com/maps/api/js?v=3.22"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<gmap></gmap>
<template id="gmap">
<div id="map"></div>
</template>
A component and a custom handler are completely different things.
Custom binding
Basically a custom binding have access to:
the HTML component where it's used
the bound value (expression supplied to the binding)
all the other bindings in the element
the binding context of the element, from which you can acces to $root, $parent, and so on
Its definition includes two functions:
init: that allows to do the initial setup, like initializing widgets, setting event handlers and so on
update: it's called after init. In that moment you can access properties (including observable properties) through the binding, all the element bindings, the context and so on. This creates subscriptios that will call update when any of the accessed observable changes.
So a custom binding shuld be used when you need to interact directly with the DOM element, for example to modify its properties, initialize widgets, subscribe to events and so on
Component
A component is completely different. When you define a componente you must define:
a template, which is a set of DOM elements, usually with bindings
a viewmodel (usually a constructor or a factory)
When you use the component:
the viewmodel is instanced
the template is loaded
the viewmodel is bound to the template
So, a componente allows to reuse viewmodels and templates
So, what's the difference?
A custom binding has direct access to the DOM elements, allowing to interact with them, subscribe to events, modify properties, and so on
A component is only a viewmodel, and a set of DOM elements with bindings to that particular viewmodel.
So, in the case of Google Maps, which needs to initialize a widget (the map) and interact with Map events, and respond to observable propèrties cahnges, you could never use a component, because the component doesn't allow the direct interaction with the DOM elements. (Remember is a bunch of HTML elements with bindings, and the corrresponding view model, whic can't include any logic to intercat with those elements).
A custom binding usually applies to a single element (althoug it could handle its children, like foreach). In the case of Google Maps you only need the element in which you'll show the map.
A component is usually a more or less complex set of DOM elements, which are not accesible "from the outside". The only communication with the main viewmodel is done through parameters. The component cannot directly interact with the DOM elements: it must do it via ko bindings.
So, for the case of Google Maps is clear that you need a custom binding.
It only makes sense to create a component when you want to modularize or reuse a set of DOM elements, and the related viewmodel, which can also include functionality like accessing web services (via AJAX), making computations (propbaly by using computed observables), and so on. For example, a shopping cart could be implemented using a component, which would include:
the DOM elements to show the items in the cart (probably an HTML table, and some controls)
controls to modify the cart content (for example for deleting elements, or changing quantities)
a viewmodel that show the total, the taxes and so on
functionality to store the cart for later, or pay for it (which could be ajax calls to services)
In this case the cart would have a viewmodel which would include the computed observables (to show the total and taxes), the functionality to remove items, or modify quantities, or store or pay, and so on. And a concrete set of DOM elements with bindings for this viewmodel, i.e. the HTML to show the cart and interact with it.
In the case of Google Maps a component could not be used without the help of a custom binding or with the hacky use of additional, non ko, scripts.
If you wanted to show a list of places beside a map, and modify that list, you could use a component, which would include a viewmodel with the list and related functionality, and a template including an element with the Google Maps custom binding. That would make sense: viewmodel + several elements.
Conclusion
This all means that a custom binding usually have a deep interaction with the bound DOM element, while a component has a higher level interaction with the elements, which must be done through bindings.
So, they play a role at a very different level. You cannot compare or interchange them.
If you insist on doing so, you could create a beast of a binding which behaves like a component, becasue you have full control on the elements, and full acces to the view model, but that's harder to implement than a component. And probably could do the other way round also in some esoteric way.
Binding
Binding, a custom or not, is a very simple concept that covers 2 things:
A property of a UI element changes, and thus it should update an object (ViewModel)
A property of the object (ViewModel) changes, and thus it should update the UI element.
From the above if only 1 implemented, it is called One Way Binding (because if you change the UI, it will update the object but not the other way around). If both 1 and 2 are implemented, it is called Two Way Binding.
So at any time if you think you need something to do that, you would need to use binding, custom binding if the framework does not have the binding you need.
Most likely, the maps you speak of needed something like above. And it actually did because the author says this in the first paragraph:
Concretely, you can learn how to make the maps marker part of the View and automatically change its position any time when the ViewModel behind changes.
See, the author talks about 2 above: When the ViewModel changes, change the position of UI element.
Component
A component is a concept of having a reusable item that may have a UI but not necessarily, and all the code needed to make it work packaged along with it. This way it can be reused. For example, it may simply be an input UI element that only allows numbers. All the code needed for it is packaged along with the UI element.
Now the code packaged along with it may code related to bindings. It may even have custom bindings if the framework they used did not have the binding they needed. In addition it may have additional code that has nothing to do with binding.
Furthermore, a component may have a single UI element or multiple. A good example of a component with multiple elements would be a message box.
In Conclusion
Bindings and Components are separate things. A component may have bindings within it or it may have other code to make it work or both.
In the case of the maps you speak of, they have only added a feature to it: To react to changes in the ViewModel. It is not a component because it is not self contained and reusable.
They could have done it using a component. However, if they did that and said it is a KO component, it may still have KO specific binding code packaged with it along with the ViewModel and all the UI elements needed.

Windows Phone 8.1 (runtime) additional data in OnMapTapped event

I am trying to create a Windows Phone 8.1 (Runtime) app that has a Map Control on it. I would like to attach additional data to the OnMappedTapped event or a way to grab an assigned Location ID when someone clicks on the MapIcon. Is this possible?
Yes. If you want to do something when someone clicks on a MapIcon (pushpin), then add a tap to the map and then do a search for elements that intersect the touch point using the Map.FindMapElementsAtOffset method: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.ui.xaml.controls.maps.mapcontrol.findmapelementsatoffset.aspx
or the Map.FindSubElementsForTouchTargeting method: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.ui.xaml.uielement.findsubelementsfortouchtargeting.aspx
When it comes to storing or associating data to a pushpin, I like to store my data in the standard Tag property as that's something I've been doing for a while with WPF and Silverlight. You will notice that the MapIcon/MapElement classes do not have a Tag property, however they are DependancyObjects which meanswe can easily add custom properties to these classes. Here is a simple extension I often use in my WP apps to add a Tag property to these classes.
public static class MapElementExt
{
public static readonly DependencyProperty TagProperty = DependencyProperty.Register("Tag", typeof(object), typeof(MapElement), new PropertyMetadata(null));
}
You can then set this value like this:
pushpin.SetValue(MapElementExt.TagProperty, MyPinData);
Personally, when it comes to pushpins I normally don't mess with the MapIcon/MapElement classes and just create a UIElement for my pushpin. By doing this I can easily have a lot more control over creating my pushpin and can also easily add Tap events. You can specify the location for a UIElement like this:
MapControl.SetLocation(pushpin, MyGeopoint);
And then add the pushpin to the Map.Children property.
If you want to get the coordinates for a randomly selected point on a map through a touch event you can take the pixel coordinates from the tap event and pass them through the Map.GetLocationFromOffset method. For example:
MyMap.Tapped += (s, e) =>
{
Geopoint loc;
MyMap.GetLocationFromOffset(e.GetPosition(MyMap), out loc);
};

Bind TreeView.SelectedItem to a property in the ViewModel in a WinRT app

In my Windows Store XAML app I’m using the TreeView control from the WinRTXamlToolkit and I’m attempting to two-way bind the SelectedItem property to a property on a ViewModel.
Out of the box, the SelectedItem property is read only and this makes sense because the control supports Virtualization.
I have seen some folk work around this with things like attached properties, helper methods and so forth, a great example of which is seen in this question
WPF MVVM TreeView SelectedItem
But all of the questions/solutions are not based on WinRT and all of my attempts to rework the solution code for a WinRT app have proven fruitless.
So, my question is, is this possible in a WinRT app? What am I missing?
Thanks
I'd skip trying to come up with a bindable property globally for the view model and instead use the IsSelectedBindingPath and IsExpandedBindingPath properties of the TreeView as in the debugging tools' example of the control's usage. Then when you want to select/expand an item from the view model - use a method similar to SelectItem() in my view model where I essentially set IsExpanded/IsSelected to true in item/node view models throughout the path from the root of the view model tree and load the content of the tree if the nodes in the expected path do not exist.

Flex 4.5 , How to create generic skinning library and dynamically change the theme of my AIR application?

I'm working on enterprise level AIR application, i need to change my application UI for multiple clients,it has a complex UI with more that 250 MXML skin files for all display objects such as buttons, combo box, containers, etc., Is it possible to create a generic skin library for managing skins and assets through CSS or i have to create a separate library for each of the clients?
Currently i'm duplicating the skin files for each client and changing the color values (styles) in CSS (which is the default.css for skin library) and Path data in skins.
Is there any easy way to create a skinning themes in flex 4.5 and managing assets(icons, fxg) in library?
Thanks in advance
Create a custom theme
I suppose you already know this, but creating a custom theme is simply a matter of:
creating a custom skin for every component
creating defaults.css file to assign those skins and perhaps provide some additional styling information
making sure that css file is included in the swc
applying the theme with the --theme compiler flag (or through whatever means your IDE provides)
Applying different colour schemes
You can use chromeColor and some other predefined styles to address this issue, but this approach may prove limiting. I solved this by substituting the Spark skin base classes with my own more elaborate versions. There's too much code to paste here, but it comes down to this:
I created an interface like this:
public interface IColorizedSkin {
function colorizeBorder(color:uint, lowLight:uint, highLight:uint):void;
function colorizeBackground(color:uint, lowLight:uint, highLight:uint):void;
function colorizeShadow(color:uint):void;
}
and I implemented this interface in my custom versions of:
SparkSkin
SparkButtonSkin
ColorizedItemRenderer
These three functions are called from an overridden updateDisplayList and use custom CSS style names like chromeBorderColor (which is an array of colours that expresses the base colour, the lowligth colour and the highlight colour of the border of a component).
All skins that need colorizing extend these base classes.
The defaults.css in the theme library comes with a default colour scheme, but you can override it by adding another css file with different colorizing directives to the client application.
Note that since these custom style names were not added as metadata to the components, you will only be able to assign these colours through CSS or through ActionScript, not through MXML attributes.
Colorizing icons
If you have an icon set that uses sufficiently neutral colours (for instance all icons are dark grey, or perhaps a grey gradient), you can colorize these too.
The simplest approach which works for solid colors is something like this:
if (iconDisplay) {
var colorTrans:ColorTransform = new ColorTransform();
colorTrans.color = getStyle("color");
iconDisplay.transform.colorTransform = colorTrans;
}
If you need something more finegrained, you'll have to work with a transform matrix.
Using different icons
I wouldn't bake icons into the skins, because that would reduce flexibility. I tend to include icons in the library swc, so one can access them from there.
If you need different icon sets for different client applications, simply create a swc including only these assets (i.e. no compiled code) for each set. As long as the names and paths inside those swc's are the same, you should be able to substitute one for the other.

Is there a way to add a flex skin programmatically in ActionScript?

I have various components that are skinned through a programmatic skin. The skin class references a singleton class that holds various colors to be applied to different aspects of the component. The singleton class has default colors set to variations of black/grey etc. I'm loading in custom colors from an XML file that are then loaded into the singleton. I'm applying the custom skin through a css stylesheet that is included in the main Application mxml.
The problem is that when the swf initially loads, the components that are drawn on screen are black and don't reflect the changes in color loaded from the XML file. I have some dropdown windows that show on button clicks and those dropdowns do reflect the correct colors from the XML file. Therefore, the system is working correctly, but the initial drawing of components obviously happens before the XML is loaded and applied to the singleton.
My question is, is there a way to apply a skin to an element programmatically by calling the constructor?
I have this in my css file:
.PanControlsBackground {
borderSkin:ClassReference('skins.buttons.PanControlsBackground');
}
and I'm applying the class with this:
_app.panControls.styleName = "PanControlsBackground";
Is there a way to call:
_app.panControls.styleName = new PanControlsBackground();
or something to that effect? This way, I can remove the loading of the skins in the css file and control when they are instantiated to ensure that the correct colors are applied before displaying the various components.
You could use the styleManager to manipulate the style at run time. For example,
.PanControlsBackground {
/* leave it blank */
}
And then in some script block:
styleManager.getStyleDeclaration(".PanControlsBackground").setStyle("borderSkin", skins.buttons.PanControlsBackground);
So, that's one way of changing the skin in a programmatic way.
However, I don't know much about how the garbage collection is handled on the old skins. For instance, how would the GC differ on this method of switching the skin versus just having a bunch of different CSS classes for each of your skins and switching between them? I can't really answer that.
I think one could at least say that the above method would ensure that the default (or other minimal skin you might create) is used first, and one could control when in the initialization process the other skin get's instantiated.