如何在Xamarin中创建自己的ImageCell?

时间:2015-08-20 13:20:43

标签: windows-phone-8.1 datatemplate xamarin.forms

我需要什么: 图像,标题,描述的DataTemplate。

我尝试了什么: 我试过ImageCell,但它的图像大小无法控制,因此图像不在屏幕上(在Windows Phone 8.1上)

我尝试创建CustomRenderer,无法为WP8.1执行此操作(无法从DataTemplate中的public override Windows.UI.Xaml.DataTemplate GetTemplate(Cell cell)中提取UI控件

我创建了ViewCell.View,将Image +两个Label放入Grid。但是再一次,它在WP8.1上无法正常工作。当我向上滚动时,文本会被剪切。

<ViewCell>
  <ViewCell.View>


    <StackLayout Padding="20,10,20,10">
      <Grid ColumnSpacing="10" RowSpacing="10">
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="80"></ColumnDefinition>
          <ColumnDefinition Width="Auto"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto"></RowDefinition>
          <RowDefinition Height="30"></RowDefinition>
          <RowDefinition Height="30"></RowDefinition>
        </Grid.RowDefinitions>

        <Label Text="{Binding Title}"
               Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" FontSize="Medium"
               XAlign="Start" HorizontalOptions="StartAndExpand" YAlign="Start" LineBreakMode="CharacterWrap" MinimumHeightRequest="60"
               FontAttributes="Bold"
               TextColor="Black">
        </Label>

        <Image Source="{Binding Image}"
               Grid.Row="1" Grid.RowSpan="2" Grid.Column="0"
               Aspect="AspectFill" HorizontalOptions="Start">
        </Image>

        <Label Text="{Binding Description}"
               Grid.Row="1" Grid.RowSpan="2" Grid.Column="1"
               FontSize="14" XAlign="Start" HorizontalOptions="StartAndExpand" YAlign="Start" LineBreakMode="CharacterWrap"
               TextColor="Black">
        </Label>

      </Grid>
    </StackLayout>

  </ViewCell.View>
</ViewCell>

那么,我如何创建自己的Cell或Control ImageCell的更多属性

2 个答案:

答案 0 :(得分:0)

这是我曾经写过的用于制作自定义ViewCell的代码,它有标签和图像,希望这对你有帮助(我在iOS,Android和WP上测试过这个):

public class ViewCellExtend : ViewCell
{
    Label menuText;
    Image menuImagen;

    public ViewCellExtend()
    {
        menuText = new Label();
        menuImagen = new Image()
        {
            Aspect = Aspect.AspectFit,
            HeightRequest = 30,
            WidthRequest = 30
        };

        StackLayout stContenedor = new StackLayout
        {
            Orientation = StackOrientation.Horizontal,
            HorizontalOptions = LayoutOptions.FillAndExpand,
            VerticalOptions = LayoutOptions.FillAndExpand,
            Spacing = 20,
            Children =
            {
                CreateCellBlock()
            }
        };

        View = stContenedor;
    }

    Xamarin.Forms.Layout CreateCellBlock()
    {
        StackLayout st2 = new StackLayout
        {
            Orientation = StackOrientation.Horizontal,
            VerticalOptions = LayoutOptions.FillAndExpand,
            HorizontalOptions = LayoutOptions.FillAndExpand,
            Children =
            {
                new StackLayout
                {
                    Padding = new Thickness(15,0,10,0),
                    HorizontalOptions = LayoutOptions.Start,
                    VerticalOptions = LayoutOptions.Center,
                    Children = 
                    { 
                        menuImagen
                    }
                },

                new StackLayout
                {
                    Padding = new Thickness(0,5,10,0),
                    HorizontalOptions = LayoutOptions.Start,
                    VerticalOptions = LayoutOptions.Center,
                    Children = 
                    {
                        menuText
                    }
                }
            }
        };

        st2.SetBinding(Layout.BackgroundColorProperty, new Binding("BackgroundColor"));

        return st2;
    }

    public static BindableProperty BindableTextProperty = BindableProperty.Create<ViewCellExtend, string>(ctrl =>
        ctrl.TextProperty,
        defaultValue: string.Empty,
        defaultBindingMode: BindingMode.TwoWay,
        propertyChanging: (bindable, oldValue, newValue) =>
        {
            var ctrl = (ViewCellExtend)bindable;
            ctrl.TextProperty = newValue;
        });


    public string TextProperty
    {
        get { return (string)GetValue(BindableTextProperty); }
        set
        {
            SetValue(BindableTextProperty, value);
            menuText.Text = value;
        }
    }

    public static BindableProperty BindableImageProperty = BindableProperty.Create<ViewCellExtend, ImageSource>(ctrl =>
        ctrl.ImageProperty,
        defaultValue: default(ImageSource),
        defaultBindingMode: BindingMode.Default,
        propertyChanging: (bindable, oldValue, newValue) =>
            {
                var ctrl = (ViewCellExtend)bindable;
                ctrl.ImageProperty = newValue;
            }
        );

    protected override void OnBindingContextChanged()
    {
        base.OnBindingContextChanged();
        System.Diagnostics.Debug.WriteLine(BindingContext.ToString());
    }

    public ImageSource ImageProperty
    {
        get { return (ImageSource)GetValue(BindableImageProperty); }
        set
        {
            SetValue(BindableImageProperty, value);
            menuImagen.Source = value;
        }
    }
}

答案 1 :(得分:0)

以下是使用自定义ViewCellRenderer的非常好的演示: https://github.com/xamarin/xamarin-forms-samples/tree/master/WorkingWithListviewNative

<强>机器人:

public class NativeAndroidCellRenderer : ViewCellRenderer
{
    protected override Android.Views.View GetCellCore (Xamarin.Forms.Cell item, Android.Views.View convertView, Android.Views.ViewGroup parent, Android.Content.Context context)
    {
        var x = (NativeCell)item;

        var view = convertView;

        if (view == null) {// no view to re-use, create new
            view = (context as Activity).LayoutInflater.Inflate (Resource.Layout.NativeAndroidCell, null);
        } else { // re-use, clear image
            // doesn't seem to help
            //view.FindViewById<ImageView> (Resource.Id.Image).Drawable.Dispose ();
        }

        view.FindViewById<TextView>(Resource.Id.Text1).Text = x.Name;
        view.FindViewById<TextView>(Resource.Id.Text2).Text = x.Category;

        // grab the old image and dispose of it
        // TODO: optimize if the image is the *same* and we want to just keep it
        if (view.FindViewById<ImageView> (Resource.Id.Image).Drawable != null) {
            using (var image = view.FindViewById<ImageView> (Resource.Id.Image).Drawable as BitmapDrawable) {
                if (image != null) {
                    if (image.Bitmap != null) {
                        //image.Bitmap.Recycle ();
                        image.Bitmap.Dispose ();
                    }
                }
            }
        }

        // If a new image is required, display it
        if (!String.IsNullOrWhiteSpace (x.ImageFilename)) {
            context.Resources.GetBitmapAsync (x.ImageFilename).ContinueWith ((t) => {
                var bitmap = t.Result;
                if (bitmap != null) {
                    view.FindViewById<ImageView> (Resource.Id.Image).SetImageBitmap (bitmap);
                    bitmap.Dispose ();
                }
            }, TaskScheduler.FromCurrentSynchronizationContext() );

        } else {
            // clear the image
            view.FindViewById<ImageView> (Resource.Id.Image).SetImageBitmap (null);
        }

        return view;
    }
}

<强>的iOS:

public class NativeiOSCellRenderer : ViewCellRenderer
{
    static NSString rid = new NSString("NativeCell");

    public override UIKit.UITableViewCell GetCell (Xamarin.Forms.Cell item, UIKit.UITableViewCell reusableCell, UIKit.UITableView tv)
    {
        var x = (NativeCell)item;
        Console.WriteLine (x);

        NativeiOSCell c = reusableCell as NativeiOSCell; 

        if (c == null) {
            c = new NativeiOSCell (rid);
        }

        UIImage i = null;
        if (!String.IsNullOrWhiteSpace (x.ImageFilename)) {
            i = UIImage.FromFile ("Images/" + x.ImageFilename + ".jpg");
        }
        c.UpdateCell (x.Name, x.Category, i);

        return c;
    }
}


public class NativeiOSCell : UITableViewCell  {

    UILabel headingLabel, subheadingLabel;
    UIImageView imageView;

    public NativeiOSCell (NSString cellId) : base (UITableViewCellStyle.Default, cellId)
    {
        SelectionStyle = UITableViewCellSelectionStyle.Gray;

        ContentView.BackgroundColor = UIColor.FromRGB (255,255,224);

        imageView = new UIImageView();

        headingLabel = new UILabel () {
            Font = UIFont.FromName("Cochin-BoldItalic", 22f),
            TextColor = UIColor.FromRGB (127, 51, 0),
            BackgroundColor = UIColor.Clear
        };

        subheadingLabel = new UILabel () {
            Font = UIFont.FromName("AmericanTypewriter", 12f),
            TextColor = UIColor.FromRGB (38, 127, 0),
            TextAlignment = UITextAlignment.Center,
            BackgroundColor = UIColor.Clear
        };

        ContentView.Add (headingLabel);
        ContentView.Add (subheadingLabel);
        ContentView.Add (imageView);
    }

    public void UpdateCell (string caption, string subtitle, UIImage image)
    {
        imageView.Image = image;
        headingLabel.Text = caption;
        subheadingLabel.Text = subtitle;
    }

    public override void LayoutSubviews ()
    {
        base.LayoutSubviews ();

        imageView.Frame = new CoreGraphics.CGRect(ContentView.Bounds.Width - 63, 5, 33, 33);
        headingLabel.Frame = new CoreGraphics.CGRect(5, 4, ContentView.Bounds.Width - 63, 25);
        subheadingLabel.Frame = new CoreGraphics.CGRect(100, 18, 100, 20);
    }
}