1
votes

Windows phone 8 with Caliburn.Micro 2.0.1 cannot bind to LongListSelector. For Caliburn tries to bind items to Visibility property. Here is XAML

<phone:LongListSelector
    x:Name="Items"
    ItemTemplate="{StaticResource MyItemTemplate}">
</phone:LongListSelector>

and view model property is pretty basic:

    IObservableCollection<Item> _Items;
    public IObservableCollection<Item> Items
    {
        get { return _Items; }
        set 
        {
            _Items = value;
            NotifyOfPropertyChange(() => Items);
        }
    }

    public class Item : PropertyChangedBase
    {
        string _Name;
        public string Name
        {
            get { return _Name; }
            set { _Name = value; NotifyOfPropertyChange(() => Name); }
        }
    }

Here is the debug output

System.Windows.Data Error: 'MS.Internal.Data.DynamicValueConverter' converter failed to convert value 'Caliburn.Micro.BindableCollection`1[Checklists.ViewModels.ItemsPageViewModel+Item]' (type 'Caliburn.Micro.BindableCollection`1[CLS.ViewModels.ItemsPageViewModel+Item]'); BindingExpression: Path='Items' DataItem='CLS.ViewModels.ItemsPageViewModel' (HashCode=38524289); target element is 'Microsoft.Phone.Controls.LongListSelector' (Name='Items'); target property is 'Visibility' (type 'System.Windows.Visibility').. System.InvalidOperationException: Can't convert type Caliburn.Micro.BindableCollection`1[CLS.ViewModels.ItemsPageViewModel+Item] to type System.Windows.Visibility.
   at MS.Internal.Data.DefaultValueConverter.Create(Type sourceType, Type targetType, Boolean targetToSource)
   at MS.Internal.Data.DynamicValueConverter.EnsureConverter(Type sourceType, Type targetType)
   at MS.Internal.Data.DynamicValueConverter.Convert(Object value, Type targetType, Object parameter, CultureInfo culture)
   at System.Windows.Data.BindingExpression.ConvertToTarget(Object value). 
2

2 Answers

2
votes

The convention you're trying to make use of here is the one Caliburn.Micro has set up for ItemsControl, unfortunately it doesn't appear that LongListSelector inherits from ItemsControl. It's odd that it doesn't so you'd assume everything would just work.

A very basic convention for LongListSelector could be added with the following

ConventionManager.AddElementConvention<LongListSelector>(LongListSelector.ItemsSourceProperty, "DataContext", "Loaded");

which would be called in your Bootstrapper. Note that this convention does't set up a default ItemTemplate that the one for ItemsSource does.

Edit: The first property is used for property binding conventions, if you have a property matching the x:Name then this is the property bound to.

The second is the parameter property, if you refer to the element as a parameter in a message such as cm:Message.Attach="DoStuff(Items)" then what property is used.

The third is event that fires the action if there is one attached.

The one mentioned in the comments

ConventionManager.AddElementConvention<LongListSelector>(LongListSelector.Items‌​SourceProperty, "SelectedItem", "SelectionChanged");

is better in that if you're using any of the other features that require the second two properties. The first convention simply uses boiler plate parameters.

1
votes

which makes sense its not a bug since LongListSelector isn't in the ConventionManager list of controls for windows Phone. You would have to add it as a custom convention for that control. Otherwise just bind normally...