Giter Site home page Giter Site logo

mvvmcross / mvvmcross Goto Github PK

View Code? Open in Web Editor NEW
3.8K 238.0 1.3K 73.88 MB

The .NET MVVM framework for cross-platform solutions, including Android, iOS, MacCatalyst, macOS, tvOS, WPF, WinUI

Home Page: http://mvvmcross.com

License: Microsoft Public License

C# 97.99% Pascal 1.94% Puppet 0.07%
mvvmcross c-sharp xamarin mvvm android dotnet monodroid nuget ios wpf

mvvmcross's Introduction

MvvmCross

Twitter: @MvvmCross license Build Status NuGet NuGet Pre Release MyGet OpenCollective OpenCollective CodeFactor

๐Ÿ‘€ Check out mvvmcross.com to get started with MvvmCross ๐Ÿ‘€

MvvmCross is a opinionated cross-platform MVVM framework. It enables developers to create apps using the MVVM pattern in the .NET ecosystem. We support Android, iOS, MacCatalyst, TvOS, macOS, WinUI, WPF. Using MvvmCross allows for better code sharing by allowing you to share behavior and business logic between platforms.

Among the features MvvmCross provides are:

  • ViewModel to View bindings using own customizable binding engine, which allows you to create own binding definitions for own custom views
  • ViewModel to ViewModel navigation, helps you share behavior on how and when to navigate
  • Inversion of Control through Dependency Injection and Property Injection
  • Plugin framework, which lets you plug-in cool stuff like GPS Location, Localization, Sensors, Binding Extensions and a huge selection of 3rd party community plug-ins

MvvmCross is extendable by you. We strive to let as much code be configurable and overridable, to let the developer decide how they want to use the framework. However, the framework is very usable without doing anything.


Check out the MvvmCross docs


Installation

Grab the latest MvvmCross NuGet package and install in your solution.

Install-Package MvvmCross

Make sure that both the shared core project and your application projects include the NuGet. For more details please visit the Getting Started documentation, which also provides easier ways, through Visual Studio and Xamarin Studio plugins to install and manage MvvmCross in your project.

Filing issues

We want to keep the GitHub issues list for bugs, features and other important project management tasks only. If you have questions please see the Questions & support section below.

When filing issues, please select the appropriate issue template. The best way to get your bug fixed is to be as detailed as you can be about the problem. Providing a minimal git repository with a project showing how to reproduce the problem is ideal. Here are a couple of questions you can answer before filing a bug.

  1. Did you try find your answer in the documentation
  2. Did you include a snippet of the broken code in the issue?
  3. Can you reproduce the problem in a brand new project?
  4. What are the EXACT steps to reproduce this problem?
  5. What platform(s) are you experiencing the problem on?

Remember GitHub issues support markdown. When filing bugs please make sure you check the formatting of the issue before clicking submit.

Contributing code

We are happy to receive Pull Requests and code changes. Please read CONTRIBUTING.md for more information.

Questions & support

Backers

Support us with a monthly donation and help us continue our activities. [Become a backer]

Sponsors

Sponsors

Become a sponsor and get your logo on our README on Github with a link to your site. [Become a sponsor]

Backers

Licensing

MvvmCross is licensed under the MS-PL License

  • MonoCross was the original starting point for this project, and was used as a reference under MIT
  • Tiny bits of MvvmLight are redistributed and modified under MIT
  • Messenger ideas from JonathanPeppers/XPlatUtils under Apache License Version 2.0, and from GrumpyDev/TinyMessenger under simple license of "THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY"
  • Color codes under MIT License
  • Some bits of Mvvm.Async are redistributed and modified under MIT License

Acknowledgements

  • Thanks to McCannLondon for sponsoring the initial part of this work
  • Thanks to JetBrains for a community Resharper license to use on this project

.NET Foundation

This project is supported by the .NET Foundation.

mvvmcross's People

Contributors

andres-gimenez avatar andyci avatar b099l3 avatar cheesebaron avatar csteeg avatar danielcweber avatar dependabot-preview[bot] avatar dependabot[bot] avatar dexyon avatar ehuna avatar garfield550 avatar guillaume-fr avatar hackmodford avatar heytherewill avatar hollywoof avatar jz5 avatar kjeremy avatar lothrop avatar lrp-sgravel avatar marcbruins avatar martijn00 avatar mvanbeusekom avatar nickrandolph avatar nmilcoff avatar orzech85 avatar plac3hold3r avatar stoneman avatar tbalcom avatar thefex avatar tofutim avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mvvmcross's Issues

Problems with generic uiviewcontroller inheritance in 6.0.0.2 of MonoTouch

No one has reported any errors yet, but I'm tracking this problem reported in MonoCross (thanks Ben!)


Email from Ben was:


It's true that MonoCross source code will not compile with MonoTouch 6.0.2 but will with MonoTouch 6.0.3 (currently in Beta). The compiler error occurs because of an identified bug with subclassing CocoaTouch objects with classes utilizing generics. In MonoTouch 6.0.3 the error is switched to a warning.

Generics are relied on in the MonoCross.Touch project as a convienence for implementing the IMXView interface within CocoaTouch UIView subclasses. The MonoCross.Touch classes are there as boiler plate code, and the abstract classes are entirely optional. To remove the boiler plate code from utilization simply remove the offending classes from the MonoCross.Touch project; and in your Touch container project implement the IMXView interface manually for each class which inherits from the offending boiler plate abstract classes.

... this compile error only occurs when you compile for the device, and does not appear when compiling for the simulator. Just another reason to "test early and often on your target devices". Don't rely on simulators for unit/integration testing.

NOTE: This only occurs with 6.0.2 and is fixed in MonoTouch 6.0.3 with a switch from a compiler error to a compiler warning. The warning doesn't fix the possible bug, but does provide developers an opportunity to proceed with caution. I still continue to use the boiler plate code.

Links to more info:

https://bugzilla.xamarin.com/show_bug.cgi?id=7547

http://stackoverflow.com/questions/12722285/generic-reference-type-error-monotouch

Android: MvxBindableListItemView instances leaking

Hello,

consider the following layout:

-cirrious.mvvmcross.binding.android.views.MvxBindableLinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
local:MvxItemTemplate="@layout/itemlayout"
local:MvxBind="{'ItemsSource':{'Path':'Items'}}" />

where "Items" will be an object implementing INotifyCollectionChanged and "itemlayout" is

-FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res/MyApp"
android:layout_width="44dp"
android:layout_height="wrap_content">
-TextView
android:background="#ffdddddd"
android:layout_width="40dp"
android:layout_height="28dp"
android:textColor="#ff000000"
android:gravity="center"
local:MvxBind="{'Text':{'Path':'ID'}}/>
-/FrameLayout-

then I found the created instances of MvxBindableListItemView (and the contained FrameLayout and TextView) to be leaking. Moreover, MvxJavaContainer instances leak in roughly the same number.

There is no leaking when the itemlayout is not bound.

What I found out using the Dalvik Debug Monitor and the Eclipse Memory Analyzer ist that all MvxBindableListItemView, FrameLayout and TextView instances are marked as residing on the native stack, they mainly hold circular references to another (with some ColorDrawable instances in between). I couldn't really find any Java-Class holding to all that instances so I assume the references are kept alive by the binding on the .net-side (with MvxJavaContainer possibly bridging the two sides).

Touch missing ICommand?

I just switched to vNext and trying to compile the whole solution in VS2010. When doing so I get a lot of errors, only for the Touch projects, which say that ICommand is missing. Looking in the System.Windows.Touch it seems to be true as the ICommand here is called ICommand2. It seems to be on purpose as there is a comment saying that System.Windows.Input is already contained in the latest version of Monotouch. I does not seem to be the case, or what version are you referring to?

MvxActionBasedBindableTableViewSource.GetOrCreateCell For in MonoTouch

Hi,
it seems, that MVVMCross is not using the possibility of reusing cells in iOS UITableView, if I'm using the MvxActionBasedBindableTableViewSource.

In GetOrCreateCell method MVVMCross is trying to get a cached cell with tableView.DequeueReusableCell(CellIdentifier), but the CellIdentifier is not the one given in the constructor, but the const NSString("MvxDefaultBindableTableViewCell"). So it will never find a cell to reuse.

You can reproduce this with your Sponsors Table in the conference demo.

To check if it is working at all, I had set the ReusableIdentifier of my cell to "MvxDefaultBindableTableViewCell". So the reusing is working properbly, but now binding is not working as expected anymore. The cell will only be refreshed, once it is scrolled out of sight and back in.

Can you give me a hint, how to get both working ? Reusing of cells and the direct refresh ?

Greetings Oliver

Binding numeric types

Hi Stuart,

Today I tried to bind some float value to an editbox and got System.ArgumentException: failed to convert parameters error.

Debugging MVVMCross, led me to MvxPropertyInfoSourceBinding class SetValue function.

Instead of Convert.ChangeType(value, PropertyInfo.PropertyType)

pls. use

PropertyInfo.SetValue(Source, Convert.ChangeType(value, PropertyInfo.PropertyType), null); (see http://stackoverflow.com/questions/1398796/casting-with-reflection).

Regards,

Levente

Allow value types in the ViewModel navigation

ints, longs, floats, doubles would all be nice...

You could also consisder adding serializable objects - but I'd be worried that people would not understand that the object would indeed be serialized as part of the navigation.

Should MvxSimpleBindingActivity have a MvxUnconventionalViewAttribute ?

Hi,

whenn you use a simplified setup as described here, you are unable to have more than one MvxSimpleBindingActivity-derived class in your project since MvxBaseSetup.GetViewModelViewLookup will try to map Views to ViewModels and ends up with typeof(object) for the ViewModel type for each activity, resulting in an ArgumentException when creating the Dictionary (because the key is used multiple times). This can be circumvented by either overriding GetViewModelTypeMappingIfPresent in your setup class or by applying the MvxUnconventionalViewAttribute to the activities. Shouldn't MvxSimpleBindingActivity have an MvxUnconventionalViewAttribute by default then? If not, the possibility to avoid this error by applying the attribute manually should be mentioned in the docs.

Regards
Daniel

Releasing memory of viewmodels

Hi,

Is there any way to help the GC releasing memory, ensuring viewmodel objects are disposed correctly. I have been through your samples but I cant seem to find any examples.

I am releasing bitmaps etc. however the code is still leaking and it might be many of objects created in the viewmodels.

Do you have any thoughts on this?

Regards

Bjarke

MvxBindableGridView

Hi Stuart,

Not an issue, but a request for an new component.

I've tried it on Android:

You have a MvxBindableListView. I just copy/pasted the code into a MvxBindableGridView (inheriting from GridView instead of ListView). And it works out of-the-box!!!!

Why don't you put it in your framework?
You did a great job!

Unable to work with ViewModel property in monodroid

Hello,
I added this line to OnViewModel method in CustomerListView.cs (monodroid CustomerManagement project):
System.Diagnostics.Debug.WriteLine("find customer:" + ViewModel.Customers.First(c => c.ID == "1").Name);

The project doesn't compile because it needs System.Windows.dll assembly reference.
Do I have to change to IList instead of IObservableCollection ? Is it a limitation ?

Thanks in advance.

Localization improvement: Check if standard language exists then process

Hello,

I was playing with Localization plugin and it appears that if a sub language folder for example fr-be or es-ar isn't found, the default language is displayed. It would be great to search for the standard language fr or es before switching to the default one. I tweaked the LoadResources from MvxTextProviderBuilder.cs like this:

public void LoadResources(string whichLocalisationFolder)
{
foreach (var kvp in ResourceFiles)
{
try
{
TextProvider.LoadJsonFromResource(_generalNamespaceKey, kvp.Key, GetResourceFilePath(whichLocalisationFolder, kvp.Value));
}

if !NETFX_CORE

            //catch (ThreadAbortException)
            //{
            //    throw;
            //}

endif

            catch (Exception exception)
            {
                MvxTrace.Trace(MvxTraceLevel.Warning, "Language file could not be loaded for {0}.{1} - {2}", whichLocalisationFolder, kvp.Key, exception.ToLongString());
                if (whichLocalisationFolder.Contains("-"))
                {
                    string standardLocalisationFolder = whichLocalisationFolder.Substring(0, whichLocalisationFolder.IndexOf("-"));
                    try
                    {
                        TextProvider.LoadJsonFromResource(_generalNamespaceKey, kvp.Key, GetResourceFilePath(standardLocalisationFolder, kvp.Value));
                    }

if !NETFX_CORE

                    //catch (ThreadAbortException)
                    //{
                    //    throw;
                    //}

endif

                    catch (Exception exceptionStandard)
                    {
                        MvxTrace.Trace(MvxTraceLevel.Warning, "Language file could not be loaded for {0}.{1} - {2}", standardLocalisationFolder, kvp.Key, exceptionStandard.ToLongString());
                    }
                }
            }
        }
    }

You can add a Boolean to check whether or not you want to use this feature.

Hope it will help to improve MvvmCross.

Notification of update between View and ViewModel

Again, not an issue, but an improvement (and again, only from my android point-of-view):

I have several activities/views, where I switch very often from one activity to another (like Modal Windows in other environments). I need to notify properties changed when the activity is resumed, restarted, etc.

Do you think it's possible to put in your code something like that:

 public abstract class MvxActivityView<TViewModel> .... 
 {     
       protected override void OnResume()
      {
            ViewModel.NotifyOnResume();
           ....  <previous code> .....
      }    

Where "NotifyOnResume()" (or more "crossplatform" names) is an interface method of IMvxViewModel (or an inheriting class).

This way, users can create "NotifyOnResume()" methods to execute code from the viewmodel.

Touch missing ICommand (still)

I am currently trying to get the vNext branch to compile successfully using MonoTouch on OSX, but I keep getting errors about System.Windows.Input.ICommand being unavailable. Looking at the MvvmCross.Binding.Touch project is says that System.Windows "Assembly not available for Mono for iPhone (in Mono 2.10.9)". I am currently using MonoTouch 6.0.6.

Thoughts?

MvxPictureChooserTask & MfA 4.2.2

Just a warning to all users. MfA 4.2.2 has bug in Bitmap.Compress, thus MvxPictureChooserTask's LoadInMemoryBitmap function will give you an object accessed while it is disposed error.

Solution revert to 4.2.1 or upgrade to 4.2.3 Beta.

Binded properties are being set multiple times

Hi,
Great work you have done here.
We have an issue in our project which is an android project. We have a MvxBindableListView which contains a number of tablecells(TableStudentViewModel). Each table cell contains our own implementation of an imageview (UmbracoImageView). The imageview has a property which is binded to a property on the table cell object - local:MvxBind="{'ImageData':{'Path':'ImageIconData'},'HideImage':{'Path':'Hidden'}}". When the property is set on the tablecell object, the property is set on the imageview multiple times, which leads to the imageview loading its image multiple times leading to memory issues and the number of GRefs to hit 2000 chrashing the emulator.

I hope you can give a hint how to solve this issue and please ask for more code if needed.

The object binded to the table cell:

namespace CmsApp.Core.ViewModels.Items
{
    public class TableStudentViewModel : BaseItemViewModel
    {
        private Student _student;

        private string[] _imageIconData;
        private bool _disableAttendanceFeature;
        private string[] _checkMarkImageDataImageData;

        public Student Student
        {
            get { return _student; }
            set { _student = value;CheckMarkSet(); }
        }

        public string[] CheckMarkImageData
        {
            get { return _checkMarkImageDataImageData; }
            set { _checkMarkImageDataImageData = value; FirePropertyChanged(() => CheckMarkImageData); }
        }


        public string[] ImageIconData
        {
            get { return _imageIconData; }
            set { _imageIconData = value; }
        }

        public string Title { get { return Student.GivenName + " " + Student.FamilyName; } }

        public string FamilyName { get { return Student.FamilyName; } }

        public string BirthDate { get { return Student.Cprnr.Substring(0,6); } }

        public string ImageUrl { get { return Student.ImageFileURL; } }

        public IMvxCommand MarkingPushed
        {
            get { return new MvxRelayCommand(ChangeCheckMarkSet); ; }
        }

        public bool DisableAttendanceFeature
        {
            get { return _disableAttendanceFeature; }
            set { _disableAttendanceFeature = value; FirePropertyChanged(() => DisableAttendanceFeature); }
        }

        public bool Hidden
        {
            get { return false; }

        }
        private void CheckMarkSet()
        {
            MvxTrace.Trace("no action");

            UmbracoImageItem image;
            if (Student.CurrentAttendence.IsAttending)
            {
                image = new UmbracoImageItem() {Id = 0, Name = "accept.png"};
            }
            else
            {
                image = new UmbracoImageItem() {Id = 0, Name = "error.png"};
            }

            CheckMarkImageData = new string[] { image.Id.ToString(), image.Name, ImageRequestOption.Resize.ToString(), ImageType.Image.ToString(), true.ToString() };
        }

        private void ChangeCheckMarkSet()
        {
            MvxTrace.Trace("no action");
            if (DisableAttendanceFeature)
            {
                return;
            }

            UmbracoImageItem image;
            if (!Student.CurrentAttendence.IsAttending)
            {
                Student.CurrentAttendence.IsAttending = true;
                Student.CurrentAttendence.Modified = true;
                image = new UmbracoImageItem() { Id = 0, Name = "accept.png" };
            }
            else
            {
                Student.CurrentAttendence.IsAttending = false;
                Student.CurrentAttendence.Modified = true;
                image = new UmbracoImageItem() { Id = 0, Name = "error.png" };
            }

            CheckMarkImageData = new string[] { image.Id.ToString(), image.Name, ImageRequestOption.Resize.ToString(), ImageType.Image.ToString(), true.ToString() };

        }
    }
}

AXML for the table cell:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res/dk.appsfabrikken.cmsapp"
    android:id="@+id/tableViewItem"
    android:layout_width="fill_parent"
    android:layout_height="80dp"
    android:paddingBottom="1dp"
    android:background="@drawable/down">
  <LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
 android:layout_gravity="center"
android:layout_marginLeft="10dp">
    <CmsApp.Droid.Controls.UmbracoImageView
        android:id="@+id/viewImagePreview"
        android:layout_width="80dp"
        android:layout_height="80dp"
         android:scaleType="centerCrop"
        android:padding="5dp"
        local:MvxBind="{'ImageData':{'Path':'ImageIconData'},'HideImage':{'Path':'Hidden'}}"
      />
    <LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
 android:layout_gravity="center"
   android:layout_marginLeft="5dp">
      <TextView
          android:layout_gravity="center_vertical"
                android:id="@+id/title"
                android:text=""
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                local:MvxBind="{'Text':{'Path':'Title'}}" />
      <TextView
          android:layout_gravity="center_vertical"
                android:id="@+id/title"
                android:textSize="10dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                local:MvxBind="{'Text':{'Path':'BirthDate'}}" />
    </LinearLayout>
  </LinearLayout>
  <CmsApp.Droid.Controls.UmbracoImageView
 android:id="@+id/checkmark"
 android:layout_width="35dp"
 android:layout_height="35dp"
 android:layout_gravity="center_vertical|right"
 android:src="@drawable/imageaccept"
    local:MvxBind="{'Click':{'Path':'MarkingPushed'},'ImageData':{'Path':'CheckMarkImageData'}}"
 />

</FrameLayout>

From The table view:

<cirrious.mvvmcross.binding.android.views.MvxBindableListView
           android:padding="5dp"
              android:background="@android:color/transparent"
           android:id="@+id/ListView"
           android:layout_width="fill_parent"
           android:layout_height="wrap_content"
           android:orientation="vertical"
           android:fastScrollEnabled="false"
           local:MvxItemTemplate="@layout/tableviewprotocolitem"
           local:MvxBind="{'ItemsSource':{'Path':'TableCells'}}"
      />

Build to root level directories

I would love to get a CI system in place... However, the complexity of supporting MT, MD, WP7 and WinRT makes me brain melt!

As an interim step, it would be nice if we could change the build directories to build to folders off of the solution root.

This must happen! And soon!

In old tree (master) you can't override an IoC registration

One more small difference vNext to master
In vNext you can override a registration
i.e.
RegisterServiceInstance(p1);
RegisterServiceInstance(p2);
will man this.GetService() returns p2
but in the old master tree
this.GetService() returns p1
which is a bug really :/

Add a Messenger plugin

It's easy to add this...

But I've been asked for this several times now...

Maybe TinyMessenger? or maybe a weak reference Messenger...

Android.Widget.ItemEventArg is obsolete Use AdaptorView.ItemClickEventArgs instead

I am trying to get the examples up and running on a Mac so I am using MonoDevelop. I have updated it to the latest release on the Beta channel but when I attempt to compile the Tutorial I get a build error "Android.Widget.ItemEventArg is obsolete Use AdaptorView.ItemClickEventArgs" instead at the OnItemClick line in the code below:

'
public class MvxBindableAutoCompleteTextView
: AutoCompleteTextView
{
public MvxBindableAutoCompleteTextView(Context context, IAttributeSet attrs)
: this(context, attrs, new MvxFilteringBindableListAdapter(context))
{
this.ItemClick += OnItemClick;
}

    public MvxBindableAutoCompleteTextView(Context context, IAttributeSet attrs, MvxFilteringBindableListAdapter adapter)
        : base(context, attrs)
    {
        var itemTemplateId = MvxBindableListViewHelpers.ReadTemplatePath(context, attrs);
        adapter.ItemTemplateId = itemTemplateId;
        Adapter = adapter;
        this.ItemClick += OnItemClick;
    }

    private void OnItemClick(object sender, ItemEventArgs itemEventArgs)
    {
        MvxTrace.Trace("Item clicked {0}", itemEventArgs.Position);
        var selectedObject = Adapter.ItemsSource[itemEventArgs.Position];
        MvxTrace.Trace("Item is {0}", selectedObject);
        SelectedObject = selectedObject;
    }

'

Excuse the formatting! Jason

MvxAndroidViewPresenter Close method bug

Hello Slodge,

I think that in Cirrious.MvvmCross.Android.Views.MvxAndroidViewPresenter Close method instead of equal you shoud use not equal in the code bellow:

var viewModel = view.ReflectionGetViewModel();
if (toClose == viewModel) //shouldn't be != ??
{
MvxTrace.Trace(MvxTraceLevel.Warning, "Cannot close viewmodel - current activity does not match the requested viewmodel");
return;
}

Dialog.Touch: StyledStringElement TextLabel background is black when extraInfo is null

This has been fixed Upstream, but MvvmCross uses an old version of MonoTouch.Dialog.

But the problem is when _extraInfo is null the Background property for the cell.TextLabel is set to null, which results in a black background for it.

A workaround is to explicitly set one of the properties in the ExtraInfo class when instantiating a StyledStringElement I.e.:

new StyledStringElement("Update Frequency", "", UITableViewCellStyle.Subtitle)
{
BackgroundColor = UIColor.White
}.Bind(this, "{'Value':{'Path':'UpdateFrequency.DisplayName'}}")

In the upstream version the if (_extraInfo == null) check in the PrepareCell method uses the ClearBackground method instead of setting the two backgrounds to null.

https://github.com/migueldeicaza/MonoTouch.Dialog/blob/master/MonoTouch.Dialog/Elements.cs#L830

Binding ignores layout parameters

Hi Stuart,

I will try not to make it a bad habit writing to you every day.
However I am having an issue again with the mvxbindable list. I want to add two objects to the list and make them fill the entire screen however it seems that the layout parameter fill_parent of each list item is ignored.

The bindable list is added the following way:

<
cirrious.mvvmcross.binding.android.views.MvxBindableListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:fastScrollEnabled="true"
local:MvxItemTemplate="@layout/accordionitem"
local:MvxBind="{'ItemsSource':{'Path':'AccordionItems'}}"
/>
From giving it a background color I can see the bindablelist fills the view as it should however if I fill it with two objects with following axml they wont fill the entire view which makes me a bit puzzeled. The rootlayout specifies fill_parent and so do the sublayouts.

Do you have suggestions?

accordionitem.axml:

<
FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res/dk.appsfabrikken.cmsapp"
android:id="@+id/accordionitem_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@android:color/white">

<ImageView
  android:id="@+id/expandIcon"
  android:layout_width="18dp"
  android:layout_height="18dp"
  android:src="@drawable/arrow_left"
  android:scaleType="centerInside"
  android:layout_marginLeft="16dp"
  android:layout_marginRight="16dp"
  android:layout_gravity="center_vertical|center_horizontal"
/>

<ImageView
  android:id="@+id/collapseIcon"
  android:layout_width="18dp"
  android:layout_height="18dp"
  android:src="@drawable/arrow_down"
  android:scaleType="centerInside"
  android:layout_marginLeft="16dp"
  android:layout_marginRight="16dp"
  android:visibility="gone"
  android:layout_gravity="center_vertical|center_horizontal"
/>

<TextView
  android:id="@+id/btnAccordionItem"
  android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:textColor="#7B8D3F"
  android:layout_gravity="center|left"
  local:MvxBind="{'Text':{'Path':'Title'}}"
/>

main view axml:

<
RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res/dk.appsfabrikken.cmsapp"
android:id="@+id/schemedetailsview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#EAEAEA">

<!-- topbar and lecture info container -->
<LinearLayout
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content">

  <LinearLayout
    android:minWidth="25px"
    android:minHeight="25px"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
  </LinearLayout>

  <LinearLayout
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <include
      android:id="@+id/horizontal_line1"
      layout="@layout/HorizontalRuleView"
    />

    <LinearLayout
      android:orientation="horizontal"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:background="@android:color/white">

      <TextView
        android:id="@+id/title"
        android:textStyle="bold"
        android:textColor="#000000"
        android:text="@string/SchemeTitle"
        android:layout_width="100dp"
        android:layout_height="20dp"
        android:layout_marginRight="20dp"
        android:paddingLeft="10dp"
      />

      <TextView
        android:id="@+id/titletext"
        android:textStyle="bold"
          android:textColor="#000000"
        local:MvxBind="{'Text':{'Path':'Title'}}"
        android:layout_width="wrap_content"
        android:layout_height="20dp"
        android:layout_toRightOf="@id/title"
      />

    </LinearLayout>

    <include
      android:id="@+id/horizontal_line2"
      layout="@layout/HorizontalRuleView"
    />

    <LinearLayout
      android:orientation="horizontal"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:background="@android:color/white">

      <TextView
        android:id="@+id/time"
        android:textStyle="bold"
        android:textColor="#000000"
        android:text="@string/SchemeTime"
        android:layout_width="100dp"
        android:layout_height="20dp"
        android:layout_marginRight="20dp"
        android:paddingLeft="10dp"
      />

      <TextView
        android:id="@+id/timetext"
        android:textStyle="bold"
          android:textColor="#000000"
        local:MvxBind="{'Text':{'Path':'TimeText'}}"
        android:layout_width="wrap_content"
        android:layout_height="20dp"
        android:layout_toRightOf="@id/time"
      />

    </LinearLayout>

    <include
      android:id="@+id/horizontal_line3"
      layout="@layout/HorizontalRuleView"
    />

    <LinearLayout
      android:orientation="horizontal"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:background="@android:color/white">

      <TextView
        android:id="@+id/room"
        android:text="@string/SchemeRoom"
        android:layout_width="100dp"
        android:layout_height="20dp"
        android:layout_marginRight="20dp"
        android:paddingLeft="10dp"
        android:textColor="@android:color/Black"
        android:textStyle="bold"
      />

      <TextView
        android:id="@+id/roomtext"
        local:MvxBind="{'Text':{'Path':'RoomText'}}"
        android:layout_width="wrap_content"
        android:layout_height="20dp"
        android:layout_toRightOf="@id/room"
        android:textColor="@android:color/Black"
        android:textStyle="bold"
      />

    </LinearLayout>

    <include
      android:id="@+id/horizontal_line4"
      layout="@layout/HorizontalRuleView"
    />

    <LinearLayout
      android:orientation="horizontal"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:background="@android:color/white">

      <TextView
        android:id="@+id/teacher"
        android:text="@string/SchemeTeacher"
        android:layout_width="100dp"
        android:layout_height="20dp"
        android:layout_marginRight="20dp"
        android:paddingLeft="10dp"
        android:textColor="@android:color/Black"
        android:textStyle="bold"
      />

      <TextView
        android:id="@+id/teachertext"
        local:MvxBind="{'Text':{'Path':'TeacherText'}}"
        android:layout_width="wrap_content"
        android:layout_height="20dp"
        android:layout_toRightOf="@id/teacher"
        android:textColor="@android:color/Black"
        android:textStyle="bold"
      />

    </LinearLayout>

    <include
      android:id="@+id/horizontal_line5"
      layout="@layout/HorizontalRuleView"
    />

  </LinearLayout>

</LinearLayout>

<!-- accordion container -->
<LinearLayout
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="0dp"
  android:layout_weight="1"
  android:background="#00FFFF">

  <cirrious.mvvmcross.binding.android.views.MvxBindableListView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:fastScrollEnabled="true"
    local:MvxItemTemplate="@layout/accordionitem"
    local:MvxBind="{'ItemsSource':{'Path':'AccordionItems'}}"
  />

</LinearLayout>

<!-- bottom bar container -->
<LinearLayout
  android:id="@+id/InnerRelativeLayout"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:background="#00FF00">

  <include
    android:id="@+id/schemeDetailsButtonRow"
    layout="@layout/buttonRow"
  />

</LinearLayout>

regards

Bjarke

Subscription for INotifyPropertyChanged

It can be handy sometimes to make to implement INotifyPropertyChanged interface in your service to notify about changes in it's state.

But in your code you will need to write something like this:

            var service = this.GetService<IWeatherService>();
            service.PropertyChanged += (sender, args) =>
            {
                if (args.PropertyName == "Temperature")
                {
                    //do smth
                }
                else if (args.PropertyName == "Loading")
                {
                    //do smth
                }
                ...
                else(args.PropertyName == "DataUnavailable")
                {
                    //do smth
                }
            };

It will be much better to use such way to do it:

            var service = this.GetService<IWeatherService>();

            subscriber = new MvxSubscriber(service)
            .Subscribe(() => Temperature, () =>
             {
                    //do smth
              })
            .Subscribe(() => Loading, () =>
             {
                    //do smth
              })
                ...
            .Subscribe(() => DataUnavailable, () =>
             {
                    //do smth
              })

...later

          subscriber.UnsubscribeAll();

P.S. Here we use the same approach for specifying properties as in FirePropertyChanged.

What do you think, should I add such syntax to application?

MvxTouchTabBarViewController and binding to badge-property

Hi,

I have a few little problems with binding a string value to the badge property of uitabbaritem.

To make this work, I had to add a MvxBindingTouchTabBarViewController for the binding function.

Also I had to change the MakeValueSafeForTarget in MvxPropertyInfoTargetBinding. The method will change a null value to string.EmptyString. For the badge-property it is needed to set it to null, to make the badge disappear.

Is it possible to add this changes to MVVMCross in a correct way ?

Greetings
Oliver

Friend access was granted to System.Net

I am getting the following error when compiling for MonoDroid using MonoTouch on the Mac:

Friend access was granted to System.Net, PublicKeyToken=7cec85d7bea7798e', but the output assembly is namedSystem.Net, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. Try adding a reference to `System.Net, PublicKeyToken=7cec85d7bea7798e' or change the output assembly name to match it

Could this be solved with the steps from your post: http://slodge.blogspot.co.uk/2012/11/thanksgiving-post-thanks-for-more.html ?

Binary releases

Now that #51 is done and we are building to root level directories, the next step is to do a binary release somehow

MvxBindableListView vnext monodroid: binding to any Collection

Hello,

It would be great to be able to bind MvxBindableListView to any Collection type.
I wanted to bind my monodroid ListView to a Dictionary<string,Type> but get an error: the problem is that the mvxbindablelistview expects an object that supports the IList interface.

I get around this problem using List<KeyValuePair<string,Type>>, but you can't get Dictionary tools in that case.

Thanks in advance for examining my request.

Allow Json Language resources to be loaded from EmbeddedResource files

Following up from this StackOverflow post (http://stackoverflow.com/questions/13455635/mvvmcross-localization-switch-at-runtime) one thing that occurred to me is that we don't really need to load Mvx Json text files from UI projects any more.

Instead I think we could quite happily use EmbeddedResource files within the Core/ViewModel project.

To make this work, we'd need to change GetTextResource so that it can use the EmbeddedResource code instead of Resource (Asset/Content based code).

Should be easy enough to do.... obviously would want to make it switchable so that old code carries on working...

Image picker in iOS needs close code changed

Need to investigate the flow - it's not currently working.

Need to consider:

_picker.DismissModalViewControllerAnimated

And need to handle _picker.Cancelled

Putting this here so it gets done....

SelectionChanged event not firing when subscribed to Scrolled event

Hi, there is a strange behavior: when subscribing to the Scrolled event of a UITableView, the SelectionChanged event of the assigned Source doesn't fire any more. If I remove the attaching to the Scrolled event, it works fine. What's going wrong there?

        SearchResultTableView.Source = _dataSource;
        SearchResultTableView.ReloadData();
        SearchResultTableView.Scrolled += HandleScrolled;

        _dataSource.SelectionChanged += (sender, args) =>
        {
            if (args.AddedItems.Count > 0)
            {
                ViewModel.ShowDetailsCommand.Execute(args.AddedItems[0]);
            }
        };

MvxBind: Warning: 15.04 Unable to bind to source is null

iOS app using MvxBindingTouchTableViewController almost identical to TwitterView for every item that is bound in the ViewModel I get a message in the standard out:

MvxBind: Warning: 15.04 Unable to bind to source is null

I'm using a CellBIndText of:

    const string CellBindingText = @"
                    {
                       'TitleText':{'Path':'HostName'},
                       'DetailText':{'Path':'Description'},
                    }";

The message appears twice for every item bound. All setup is done in ViewDidLoad() override. Everything works and appears as expected.

Bindings don't work when changing TextField values in code

If I bind my TextField to the ViewModel, then use a DatePicker to change the value of the TextField, the binding doesn't happen. If I type directly into the textField, it all works fine. Would it be possible to allow changes made by code to work too?

Using MvxBindableListView makes Commands pointing on Models instead of ViewModels

Hi Stuart,

As discussed on stackoverflow (http://stackoverflow.com/questions/12682082/mvvmcross-changing-viewmodel-within-a-mvxbindablelistview), here is my point of view on the ideal axml file:

articles_view.axml

   ...
          <Mvx.MvxBindableListView
                android:id="@+id/listviewArticle"
                android:choiceMode="singleChoice"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:orientation="vertical" 
                local:MvxItemTemplate="@layout/article_rowlayout"
                local:MvxBind="{'ItemsSource':{'Path':'Articles'}}" />    
   ...


And here is the "article_rowlayout.axml"

   ...
            <TextView
                android:id="@+id/rowArticleLabel"
                android:layout_width="0dip"
                android:layout_weight="14"
                android:layout_height="wrap_content"
                android:textSize="28dip"
                local:MvxBind="{'Text':{'Path':'Item.Label'}}" />
            <ImageButton
                android:src="@drawable/ic_modify"
                android:layout_width="0dip"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:id="@+id/rowArticleButtonModify"
                android:background="@null" 
                android:focusable="false"
                android:clickable="true"    
                local:MvxBind="{'Click':{'Path':'MyCommand'}}"
              />
   ...

The "Item" word should be a "reserved word" pointing to the "Artcicles[x]"
And without "Wrapper" programming, the "article_rowlayout.axml" should always point on the ViewModel of the MvxBindableListView instead of working in the "Articles[x]" context.

Another point of view should be to choose the viewmodel of the MvxBindableListView in the parameters:

   ...
          <Mvx.MvxBindableListView
                android:id="@+id/listviewArticle"
                android:choiceMode="singleChoice"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:orientation="vertical" 

                local:MvxViewModel="xxx"

                local:MvxItemTemplate="@layout/article_rowlayout"
                local:MvxBind="{'ItemsSource':{'Path':'Articles'}}" />    
   ...

Where "xxx" should be the class we would like to use, or maybe a reserved word telling to use the current viewmodel (the one of the MvxBindableListView).

Other points of view should be nice ...

Hugo Terelle

Allow simpler binding expressions in Droid

There's no reason we can't do simpler (less verbose) binding expressions.

e.g. we could just bind a list to:

    {'ItemsSource':'TheList','ItemClick':'TheClickCommand'}

or we could look at arrays to include Converters too

    {'Test:['TheDate', , 'TimeAgoConverter', ]}

Need to think about this, but I like the idea of making the XML/JSON shorter :)

Binding IList<T> conversion errors

In my PickerElement, which I also made a pull request for I use IList as the type of my binding. But binding this results in a lot of exceptions being thrown because of Invalid Casts, which occur in the MvxPropertyInfoSourceBinding.SetValue() method, where it tries to convert List to IList.

Normally this conversion is just fine

List<string> list2 = new List<string>();
IList<string> ilist = list2;

Though the method to convert in the MvxPropertyInfoSourceBinding is the System.Convert.ChangeType method, which in this case fails and throws an InvalidCastException and tells us that IConvertible must be implemented.

The stack trace I get is:

MvxBind: Error:   9.47 SetValue failed with exception - InvalidCastException: Value is not a convertible object: System.Collections.Generic.List`1[Cirrious.MvvmCross.Dialog.Touch.Dialog.Elements.IPickerComponent] to System.Collections.Generic.IList`1[[Cirrious.MvvmCross.Dialog.Touch.Dialog.Elements.IPickerComponent, Cirrious.MvvmCross.Dialog.Touch, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]
      at System.Convert.ToType (System.Object value, System.Type conversionType, IFormatProvider provider, Boolean try_target_to_type) [0x00228] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/Convert.cs:2627 
  at System.Convert.ChangeType (System.Object value, System.Type conversionType) [0x00040] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/Convert.cs:2183 
  at Cirrious.MvvmCross.Binding.Bindings.Source.MvxPropertyInfoSourceBinding.SetValue (System.Object value) [0x0009a] in /Volumes/MvvmCross/Cirrious/Cirrious.MvvmCross.Binding/Bindings/Source/MvxPropertyInfoSourceBinding.cs:83

So when implementing IConvertible in an new implementation of List the problems are fixed:

public class MyList<T> : List<T>, IConvertible
{
    public TypeCode GetTypeCode()
    {
        return TypeCode.Object;
    }

    //Other types were removed

    public Object ToType(Type conversionType, IFormatProvider provider)
    {
        if (conversionType == typeof(IList<T>))
        {
            return (IList<T>)this;
        }
        throw new InvalidCastException();
    }
}

var list = new MyList<string>();
IList<string> list1 = (IList<string>)Convert.ChangeType(list, typeof(IList<string>));

So is this the desired behaviour and should we always implement our own list types which implement IConvertible, or?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.