I'm trying to create a custom converter for my MvvmCross project. I'm inheriting from MvxBaseVisibilityValueConverter and just implementing the Convert method.
Do I need to implement platform specific projects as well or is there a way to reuse the platform specific visibility plugins?
I've been documenting ValueConverters in the last few days - see https://github.com/slodge/MvvmCross/wiki/Value-Converters
I've just added this example custom visibility ValueConverter to the article:
If you need to create your own Visibility ValueConverter's then the MvxBaseVisibilityValueConverter<T> and MvxBaseVisibilityValueConverter base classes can assist with this - e.g.:
public class SayPleaseVisibilityValueConverter : MvxBaseVisibilityValueConverter<string>
{
protected override MvxVisibility Convert(string value, object parameter, CultureInfo culture)
{
return (value == "Please) ? MvxVisibility.Visible : MvxVisibility.Collapsed;
}
}
Using this approach, then the plugin base class will convert the MvxVisibility to a suitable native value at runtime - so you only need to add this type of class to your core PCL project - you don't need to add native versions of the class - instead the base class from the plugin will take care of the MvxVisibility -> native Visibility conversion.
Aside> in addition to the Visibility enum support from the Plugin, recent 'Tibet' binding changes have also added custom Visible binding properties to all platforms - these are just bools so much easier to use - they should 'just work' on iOS and Android, but on Windows platforms they will only work if you switch to the "Tibet' mvx:Bi.nd style of binding (so not everyone's preferred approach!)
Related
I am now moving from my code behind xaml dp binding to using CreateBindingSet, as I believe it will be easier to maintain on long run. Previously to confirm that I haven't missed any binding, I had a Windows Phone Test project with a generic test routine - that would parse a view for all the controls, and confirm that each has a correct binding. I did this using
element.GetBindingExpression(dependencyProperty) // from System.Windows
and that's worked beautifully - validating all my views.
But now as I am changing over, all these tests are failing. Has anyone any suggestions on how I can test same thing with when the binding is applied using CreateBindingSet and .Apply.
Thanks in advance.
Rana
Reasoning behind the Madness
Being a lazy sod, I dream of a day where my View would be shared across all platforms; until then, the following would do (I have most in place and working)
BoilerPlate class that would be shared between all platforms:
#if __IOS
... needed namespaces
#else ....
public partial class FirstView
{
private new FirstViewModel ViewModel
{
get { return (FirstViewModel)base.ViewModel; }
}
private void CommonBinding()
{
var set = this.CreateBindingSet<FirstView, FirstViewModel>();
// do common bindings
set.Bind(PageText).For(c => c.Text).To(vm => vm.PageText).OneTime();
set.Apply();
}
}
Then View in Touch would be:
public partial class FirstView : MvxViewController
{
public override void LoadView()
{
// create
}
public override ViewDidLoad()
{
CommonBinding();
}
}
In theory, Views in other platform would be almost similar; just different inheritance (MvxActivity with OnCreate, and OnViewModelSet)/(MvxPhonePage with xaml/alternative, and Loaded Event for binding).
Finally, a common testing way to ensure that all the items has binding set somehow. In my mind, until autoview is supported in wp8, it's just the way to have as much shared code as possible.
I have just started on droid, and trying to make the layout compatible with xibFree, which I have already used in my touch project. If this works, I can then have shared layout between droid and touch (perhaps I should be looking at autoView anyway)
I'm personally not sure what value these tests add that much value to your application - these feel like they are operating at a level of "duplicating code" rather than actually testing any functionality.
However, this is very much down to personal opinion, and if you do want this level of testing, then I think you could do this by:
Inherit a class from https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross.BindingEx.WindowsPhone/WindowsBinding/MvxWindowsBindingCreator.cs
Override ApplyBinding so that you can capture at test time the calls made for each element
Register this class with ioc as the IMvxBindingCreator in your test harness
Use the captured lists of binding requests in your tests
I'm working on MVVMCross v3 and I want to create my own plugin, I followed this tutorial (which is for the vNext)
http://slodge.blogspot.fr/2012/10/build-new-plugin-for-mvvmcrosss.html
To be compatible for the v3 I changed IMvxServiceConsumer and GetService to Mvx.Resolve.
But on the tutorial there are :
Then, for WinRT, WindowsPhone and MonoTouch clients, you also need to provide a Loader accessor in setup.cs - like:
protected override void AddPluginsLoaders(Cirrious.MvvmCross.Platform.MvxLoaderPluginRegistry loaders)
{
loaders.AddConventionalPlugin<MyCompany.MvvmCross.Plugins.Mega.WindowsPhone.Plugin>();
base.AddPluginsLoaders(loaders);
}
How can I do that in v3?
Thanks
If you want to write a new plugin, then :
the up-to-date sample is https://github.com/slodge/MvvmCross-Tutorials/tree/master/GoodVibrations
there are some notes on this sample in https://speakerdeck.com/cirrious/plugins-in-mvvmcross
For plugin initialisation, the nuget packages now do this via bootstrap files - e.g. see the files added for Location at:
(WinRT, WinPhone, Droid) - https://github.com/slodge/NPlus1DaysOfMvvmCross/blob/master/N-08-Location/Location.Droid/Bootstrap/LocationPluginBootstrap.cs
(Touch) - https://github.com/slodge/NPlus1DaysOfMvvmCross/blob/master/N-08-Location/Location.Touch/Bootstrap/LocationPluginBootstrap.cs
The bootstrap way is the normal way to do initialisation now.
If you did want to use a non-bootstrap technique then you can do this:
In WinRT, WinPhone, and Droid, you don't need to use a loader, but you do need to call MyPlugin.PluginManager.Instance.EnsureLoaded before the plugin can be used.
In Touch, you would need to provide a loader during protected override void AddPluginsLoaders(MvxLoaderPluginRegistry loaders) - and you'd then still need to call EnsureLoaded() before the plugin can be used.
For examples of this 'old way' of working, see Setup.cs in the UI projects in https://github.com/slodge/MvvmCross-Tutorials/tree/master/Sample%20-%20TwitterSearch
I'm currently working on a project that involve a re-implementation of the Array class.
This object needs to be an Array for compatibility reasons, while I also need to keep control of what is written in.
I cannot seem to find any way to check property creation inside of a dynamic object in AS3. Something that would work like the Event.ADDED_TO_STAGE but, like, ClassEvent.PROPERTY_ADDED.
I override methods like push, splice etc, but I cannot control direct assignation : MyArray[i] = ...
Is such a thing even possible ?
Of course, I could make some kind of validations elsewhere, but this would involve accessing a part of the code I cannot modify.
Thanks for your time !
I'm not sure I follow you entirely but you may be looking for the Proxy class:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/utils/Proxy.html
An example at the bottom shows you how you can override direct assignment:
override flash_proxy function setProperty(name:*, value:*):void {
_item[name] = value;
}
Using this you would be able to dispatch a custom event that would be fired any time an item was added to your ProxyArray
I am using the URL logic for creating a dynamic Tree in Flex using action script. However the output is not properly shown (Object name is shown instead of Label).
Code is available in above mentioned URL.
Please help.
Write a correct toString() implementation of your DataTreeNode, so it would have a proper display in this tree.
An example: Provided the class DataTreeNode has a data:Object field, and this object has a urlToDisplay:String property that you want displayed. Do like this:
override public function toString():String {
if (!data) return '[null]';
return data.urlToDisplay;
}
If you only rely on simple Objects or data classes, you can use the tree's labelField or labelFunction in order to read and/or format data, which is passed to the renderer. There are no new item renderer classes needed.
New renderer should be compatible with these functions!
On a site note: item renderer are not "mostly just simple MXML classes", they are component instances. It doesn't matter how there are implemented. There are best practises like avoiding data bindings in item renderers, that's why it is common to use the markup for drawing, but implementing the views behaviour according to the Flex component live cycle. you might want to read about it in the documentation, because it is a necessary read for a Flex developer.
You will have to write an ItemRenderer that tells your tree how it should display the components. ItemRenderers are mostly just simple MXML classes that access one item each and display the data in any way you want. You will have to assign the ItemRenderer to your component.
See this article:
http://help.adobe.com/en_US/flex/using/WS03d33b8076db57b9-23c04461124bbeca597-8000.html
I'm try to put together a bare bones robotlegs-signals project but all the samples I've seen are flex ie
Index.mxml
<context:SignalCafeContext contextView="{this}"/>
SignalCafeContext.as
public class SignalCafeContext extends SignalContext
{
override public function startup():void
{
injector.mapSingleton.... etc etc
}
}
Is this possible to replace the mxml with another .as file - normally I would pass from the main class
context = new MyContext(this); // where this is DisplayObjectContainer
however super() takes no parameters in SignalContext so I might be missing something.
More Info:
libs:
as3-signals-v0.5.swc
robotlegs-framework-v1.03.swc
signals-extensions-SignalsCommandMap.swc
What you're trying would work in the current RobotLegs v.1 release (v.1.5.2). Context and its subclass SignalContext take optional params. The first param is your context view:
contextView:DisplayObjectContainer = null
Here's the SignalContext class extending Context.
Note, Context in Robotlegs 2 does not take parameters (source).
I imagine you need to start with a actionscript project instead of a flex project in FlashBuilder first.
Yes, your right, you just extend the Context class, as you can see in the basic HelloFlash robotlegs demo
mxml tags are just shorthand for actionscript classes. So I'd imagine you could start by taking a look at the auto-generated actionscript code. There is a flash builder compiler option that will let you see this. Using that as a template, you probably can't go too far wrong.