Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot Convert Lambda expression to type 'System.Type' because it is not a Delegate Type

Tags:

c#

lambda

xamarin

I am working in Xamarin.Forms, to try and create a Pop Up window which contains a ListView.

I am trying to use this structure:

var PopUp = new StackLayout
{
 BackgroundColor = Color.Black, // for Android and WP
 Orientation = StackOrientation.Vertical,
 Children =
 {
    PLZOrt_Label, // my Label on top
    SearchBarPLZOrt, // my SearchBar to the ListView
    LVPLZOrt, // The Listview (all Cities/Zip-Codes in the Datasource -> List)
 }
};

Taken from this guide page 13.

However, when I add a list view ( as detailed here ),

new Func<object> (delegate {
    ListView listView = new ListView {
    // Source of data items.
    ItemsSource = devices,

    ItemTemplate = new DataTemplate(() =>
    {
            // Create views with bindings for displaying each property.
            Label nameLabel = new Label();
            nameLabel.SetBinding(
            Label.TextProperty, "{Binding Name, Converter={StaticResource strConverter}}"
            );

            Label IDLabel = new Label();
            IDLabel.SetBinding(
                Label.TextProperty, "{Binding Path=ID, Converter={StaticResource guidConverter}}"
                );

                return new ViewCell
                    {
                        View = new StackLayout
                    {
    })
});

The "ItemTemplate" line throws up a "Cannot Convert Lambda expression to type 'System.Type' because it is not a Delegate Type"

In some other issues like this, it seems the solutions was to add a new action(() => {}) structure, but as this is a Xamarin approved method, I am not sure why I would need to implement this?

Thanks!

EDIT: With the addition of the top func line, I now get an error raised on that line, Error CS1643: Not all code paths return a value in anonymous method of type 'System.Func<object>'

like image 280
George Edwards Avatar asked Sep 22 '26 01:09

George Edwards


1 Answers

As you can see from the constructors of DataTemplate here, you need to either pass a Func<object> or a Type.

You need to return something inside your statement block in order for it to be converted to a Func<object>. Since you have no return statement, the lambda isn't converted and the compiler thinks you're trying to use the DataTemplate(Type) constructor with wrong parameters. I don't know why the C# compiler chooses this constructor - I would guess that it's the first one it finds.

The example on the documentation page for the ListView page which you linked works because it returns a new ViewCell:

// ...
ItemTemplate = new DataTemplate(() =>
{
    // Create views with bindings for displaying each property.
    Label nameLabel = new Label();
    nameLabel.SetBinding(Label.TextProperty, "Name");

    Label birthdayLabel = new Label();
    birthdayLabel.SetBinding(Label.TextProperty,
        new Binding("Birthday", BindingMode.OneWay, 
                    null, null, "Born {0:d}"));

    BoxView boxView = new BoxView();
    boxView.SetBinding(BoxView.ColorProperty, "FavoriteColor");

    // Return an assembled ViewCell.  <<--------------------------------------
    return new ViewCell
    {
        View = new StackLayout
        {
            Padding = new Thickness(0, 5),
            Orientation = StackOrientation.Horizontal,
            Children = 
            {
                boxView,
                new StackLayout
                {
                    VerticalOptions = LayoutOptions.Center,
                    Spacing = 0,
                    Children = 
                    {
                        nameLabel,
                        birthdayLabel
                    }
                }
            }
        }
    };
})
// ...

EDIT: This is what I meant by put the lambda inside a new Func<object>(...):

ListView listView = new ListView
{
    // Source of data items.
    ItemsSource = devices,

    ItemTemplate = new DataTemplate(new Func<object>(() =>
    {
        // Create views with bindings for displaying each property.
        Label nameLabel = new Label();
        nameLabel.SetBinding(
            Label.TextProperty, "{Binding Name, Converter={StaticResource strConverter}}"
        );

        Label IDLabel = new Label();
        IDLabel.SetBinding(
            Label.TextProperty, "{Binding Path=ID, Converter={StaticResource guidConverter}}"
        );

        return new ViewCell
        {
            View = new StackLayout
        };
    }));
}
like image 113
cbr Avatar answered Sep 24 '26 16:09

cbr



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!