Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using MvxVisibilityValueConverter in WPF

Tags:

wpf

mvvmcross

I'm just getting started with MVVMCross, so forgive me if this seems like a simple question. I'm trying use the MVVMCross Visibility plugin in WPF, mentioned here:

https://github.com/MvvmCross/MvvmCross/wiki/Value-Converters

I installed the plugin, and am trying to follow these steps:

Windows - use Native wrappers or Tibet Binding as described above:

Visibility="{Binding VMProperty, Converter={StaticResource Visibility}}"

When I try to do so, it can't find the resource "Visibility."

So I figured, I can add the namespace:

xmlns:visibility="clr-namespace:Cirrious.MvvmCross.Plugins.Visibility;assembly=Cirrious.MvvmCross.Plugins.Visibility"

...and then add the converter to my resources:

<visibility:MvxVisibilityValueConverter x:Key="Visibility"></visibility:MvxVisibilityValueConverter>

...but now I get:

An object of the type "Cirrious.MvvmCross.Plugins.Visibility.MvxVisibilityValueConverter" cannot be applied to a property that expects the type "System.Windows.Data.IValueConverter".

Do I have to make my own Converter for this, like this:

class MyVisibilityConverter : MvxNativeValueConverter<MvxVisibilityValueConverter>
{
}

...or am I missing something? The docs seem to indicate there's less work involved.

like image 583
user2970752 Avatar asked Nov 08 '13 23:11

user2970752


1 Answers

IValueConverter isn't currently a portable interface, and this was a deliberate decision from Microsoft. I've talked to one of the guys from the PCL team about this - he seemed very clear that they expected most value converters to be platform specific and so not to sit in shared code.

Because of this - and because MvvmCross believes many value converters will be shared - we had to introduce our own IMvxValueConverter interface inside MvvmCross. This IMvx interface can't be used directly by XAML and the Microsoft bindings - so that's the reason you need the "native" wrapping currently.

You can work around this - if you want to - by using the MvvmCross "Tibet" binding framework instead of the Microsoft one, but I think most MS-based devs are still using the MS-binding.


am I missing something? The docs seem to indicate there's less work involved.

For using value converters on Windows, the wiki says the text below - if you think this can be improved, please do contribute changes back - we're keen to keep on improving.

Using Value Converters in Windows (conventional Xaml binding)

The IMvxValueConverter interface is closely based on the IValueConverter interface used in Windows WPF and Silverlight Xaml binding. This interface is also similar (but slightly different) to the IValueConverter interface used in Windows WinRT Xaml binding.

Because these Xaml IValueConverter interfaces are not 100% identical to each other, nor to the IMvxValueConverter version, shared Mvx ValueConverters cannot be used directly in Windows Xaml binding - they must instead be wrapped for use in Xaml.

The steps to do this are similar on each Windows platform:

  • for each IMvxValueConverter class, e.g. for

     public class TheTruthValueConverter 
        : MvxValueConverter<bool, string> 
     { 
        public string Convert(bool value, Type targetType, CultureInfo cultureInfo, object parameter)
        {
            return value ? "Yay" : "Nay";
        } 
     }
    
  • in your UI project, create a 'native' wrapper using the MvxNativeValueConverter class:

     public class TheNativeTruthValueConverter
        : MvxNativeValueConverter<TheTruthValueConverter>
     {
     }
    
  • in your Xaml, include an instance of your ValueConverter as a static resource - this can be done in the Resources at App, Page or Control Xaml level, e.g.:

     <converters:TheNativeTruthValueConverter x:Key="TheTruth" />
    
  • now your converter can be used - e.g.:

     <TextBlock Text="{Binding HasAccepted, Converter={StaticResource TheTruth}}" />
    

Using Value Converters in Windows (Tibet binding)

In addition to 'traditional' Xaml bindings, MvvmCross also allows 'Tibet' binding within Windows - for more on this see wiki/Databinding.

When Tibet binding is used, then Value Converters can be accessed by name - exactly as in Droid and Touch binding - without the above native Xaml wrapping.

Further, if using 'Tibet' binding then an entire assembly's worth of value converters can be registered using the Reflection sweep technique and this can be specified at the Xaml level - meaning it can be used in both design and run-time.

To include all value converters within an Assembly at the Xaml level, then use an mvx:Import block with an inner From attribute which contains an instance of a class from that Assembly.

This may sound complicated… but actually it is quite simple.

  • Suppose you have an Assembly MyTools containing FooValueConverter, BarValueConverter, etc
  • Within this Assembly add a simple, instanciable public Class which we will use only for the import - e.g. public class MarkerClass {}
  • Then within the xaml, you can include a static resource import block like:

     <mvx:Import x:Key="MvxAssemblyImport0">
       <mvx:Import.From>
         <myTools:MarkerClass />
       <mvx:Import.From>
     </mvx:Import>
    
  • After this is done, then the ValueConverters Foo and Bar will be available for use within 'Tibet' bindings - e.g. as:

     <TextBlock mvx:Bi.nd="Text Foo(Name)" />
    
like image 122
Stuart Avatar answered Oct 15 '22 01:10

Stuart