To help with this discussion, I have published all relevant source-code on GitHub... https://github.com/WindSpirit/DroidCustomView
Basically, I wrote an Android Custom-View (Asgl.Android.Views.RatingView), that inherits from TableLayout and contains several ImageView's that get changed by public get/set properties (via MvvmCross bindings and/or AXML property attributes).
This Custom-View is used within an MvxList, MvxItemTemplate.
Here is what the MvxItemTemplate AXML code looks like...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:id="@+id/task_description"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
local:MvxBind="Text RatingValue" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
local:MvxBind="Text ScaleValue" />
<Asgl.Android.Views.RatingView
android:id="@+id/rating"
android:layout_margin="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
local:MvxBind="Rating RatingValue; Scale ScaleValue" />
</LinearLayout>
The TextView controls display data via MvvmCross bindings as expected, but the Custom-View control does not display correctly.
Based on "N-28-CustomBinding", I customize the look-and-feel of the Custom-View when Public Property setter methods are called on the View object. See also http://slodge.blogspot.ca/2013/06/n28-custom-bindings-n1-days-of-mvvmcross.html
Everything works as it should, except all of the initial MvxItemTemplate items are displayed exactly the same, even when they should appear differently. It is as though a cached image of the Custom-View is used for every list item, even though the list item properties differ in value.
Within the Custom-View, this.Parent() is never available and calling Custom-View methods like this.Invalidate() or this.InvalidateDrawable( this.myDrawable.Drawable ), don't appear to have any effect.
In other words, simply executing the following code will not necessarily result in a visual list item change during the construction of the MvxList...
public int? Rating
{
get { return _rating; }
set {
if ((value != null) && (value < -2 || value > 5))
throw new ArgumentOutOfRangeException();
if (_rating != value)
{
_rating = value;
_isUpdating = true;
try
{
var testValue = Scale ?? 0;
Rating0.Visibility = (testValue > 0) ?
ViewStates.Visible : ViewStates.Gone;
Rating1.Visibility = (testValue > 0) ?
ViewStates.Visible : ViewStates.Gone;
Rating2.Visibility = (testValue > 2) ?
ViewStates.Visible : ViewStates.Gone;
Rating3.Visibility = (testValue > 3) ?
ViewStates.Visible : ViewStates.Gone;
Rating4.Visibility = (testValue > 4) ?
ViewStates.Visible : ViewStates.Gone;
ActnGood.SetColorFilter((Rating > 0) ?
ColourGood : ColourDisabled, PorterDuff.Mode.SrcIn);
Rating0.SetImageDrawable(ActnGood);
ActnBad.SetColorFilter((Rating > 0) ?
ColourDisabled : ColourBad, PorterDuff.Mode.SrcIn);
Rating1.SetImageDrawable(ActnBad);
this.Invalidate();
// etc...
if (RatingChanged != null)
RatingChanged(this, EventArgs.Empty);
} finally {
_isUpdating = false;
}
}
}
}
public event EventHandler RatingChanged;
QUESTION: What do I need to do to have MvxList redraw one of its list items when the list items property value changes due to an MvvmCross binding?