Merge pull request #59 from jsuarezruiz/master

ListViewRenderer, CellRenderers and ListView Samples
This commit is contained in:
Frank A. Krueger 2018-01-09 16:20:29 -08:00 committed by GitHub
commit 0ab74138b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 1006 additions and 2 deletions

View File

@ -0,0 +1,71 @@
using Ooui.Forms.Extensions;
using System;
using Xamarin.Forms;
namespace Ooui.Forms.Cells
{
public class CellRenderer : IRegisterable
{
private EventHandler _onForceUpdateSizeRequested;
static readonly BindableProperty RealCellProperty =
BindableProperty.CreateAttached("RealCell", typeof(Div),
typeof(Cell), null);
public virtual CellView GetCell(Cell item, CellView reusableView, List listView)
{
var nativeCell = reusableView as CellView ?? GetCellInstance(item);
nativeCell.Cell = item;
WireUpForceUpdateSizeRequested(item, nativeCell);
UpdateBackground(nativeCell, item);
return nativeCell;
}
internal static CellView GetRealCell(BindableObject cell)
{
return (CellView)cell.GetValue(RealCellProperty);
}
internal static void SetRealCell(BindableObject cell, CellView renderer)
{
cell.SetValue(RealCellProperty, renderer);
}
protected virtual CellView GetCellInstance(Cell item)
{
return new CellView();
}
protected virtual void OnForceUpdateSizeRequest(Cell cell, CellView nativeCell)
{
nativeCell.Style.Height = (int)cell.RenderHeight;
}
protected void UpdateBackground(CellView tableViewCell, Cell cell)
{
var defaultColor = Xamarin.Forms.Color.White.ToOouiColor();
Color backgroundColor = defaultColor;
if (cell.RealParent is VisualElement element)
backgroundColor = element.BackgroundColor ==
Xamarin.Forms.Color.Default ? backgroundColor : element.BackgroundColor.ToOouiColor();
tableViewCell.Style.BackgroundColor = backgroundColor;
}
protected void WireUpForceUpdateSizeRequested(Cell cell, CellView nativeCell)
{
cell.ForceUpdateSizeRequested -= _onForceUpdateSizeRequested;
_onForceUpdateSizeRequested = (sender, e) =>
{
OnForceUpdateSizeRequest(cell, nativeCell);
};
cell.ForceUpdateSizeRequested += _onForceUpdateSizeRequested;
}
}
}

View File

@ -0,0 +1,84 @@
using System;
using System.ComponentModel;
using Xamarin.Forms;
namespace Ooui.Forms.Cells
{
public class CellView : Div, INativeElementView
{
private Cell _cell;
public Action<object, PropertyChangedEventArgs> PropertyChanged;
public CellView()
{
CreateUI();
}
public Cell Cell
{
get { return _cell; }
set
{
if (_cell == value)
return;
if (_cell != null)
Device.BeginInvokeOnMainThread(_cell.SendDisappearing);
_cell = value;
if (_cell != null)
Device.BeginInvokeOnMainThread(_cell.SendAppearing);
}
}
public Div FirstCol { get; private set; }
public Div SecondCol { get; private set; }
public Div ThirdCol { get; private set; }
public Label TextLabel { get; private set; }
public Label DetailTextLabel { get; private set; }
public Image ImageView { get; private set; }
public Div CustomView { get; private set; }
public virtual Xamarin.Forms.Element Element => Cell;
public void HandlePropertyChanged(object sender, PropertyChangedEventArgs e)
{
PropertyChanged?.Invoke(this, e);
}
private void CreateUI()
{
Style.Width = "100%";
Style.Display = "flex";
FirstCol = new Div();
AppendChild(FirstCol);
SecondCol = new Div();
AppendChild(SecondCol);
ThirdCol = new Div();
AppendChild(ThirdCol);
ImageView = new Image();
FirstCol.AppendChild(ImageView);
TextLabel = new Label();
SecondCol.AppendChild(TextLabel);
DetailTextLabel = new Label();
SecondCol.AppendChild(DetailTextLabel);
CustomView = new Div();
ThirdCol.AppendChild(CustomView);
}
}
}

View File

@ -0,0 +1,104 @@
using Ooui.Forms.Extensions;
using System;
using System.ComponentModel;
using Xamarin.Forms;
namespace Ooui.Forms.Cells
{
public class EntryCellRenderer : CellRenderer
{
private static Cell _cell;
public override CellView GetCell(Cell item, CellView reusableView, List listView)
{
TextInput nativeEntry = null;
var nativeEntryCell = base.GetCell(item, reusableView, listView);
if (nativeEntryCell == null)
nativeEntryCell = new CellView();
else
{
nativeEntryCell.Cell.PropertyChanged -= OnCellPropertyChanged;
nativeEntry = nativeEntryCell.CustomView.FirstChild as TextInput;
if (nativeEntry != null)
{
nativeEntryCell.CustomView.RemoveChild(nativeEntry);
nativeEntry.Change -= OnTextChanged;
}
}
SetRealCell(item, nativeEntryCell);
if (nativeEntry == null)
nativeEntryCell.CustomView.AppendChild(nativeEntry = new TextInput());
var entryCell = (EntryCell)item;
nativeEntryCell.Cell = item;
nativeEntryCell.SecondCol.Style.Width = "25%";
_cell = nativeEntryCell.Cell;
nativeEntryCell.Cell.PropertyChanged += OnCellPropertyChanged;
nativeEntry.Change += OnTextChanged;
WireUpForceUpdateSizeRequested(item, nativeEntryCell);
UpdateBackground(nativeEntryCell, entryCell);
UpdateLabel(nativeEntryCell, entryCell);
UpdateText(nativeEntryCell, entryCell);
UpdatePlaceholder(nativeEntryCell, entryCell);
UpdateLabelColor(nativeEntryCell, entryCell);
return nativeEntryCell;
}
private static void OnCellPropertyChanged(object sender, PropertyChangedEventArgs e)
{
var entryCell = (EntryCell)sender;
var realCell = (CellView)GetRealCell(entryCell);
if (e.PropertyName == EntryCell.LabelProperty.PropertyName)
UpdateLabel(realCell, entryCell);
else if (e.PropertyName == EntryCell.TextProperty.PropertyName)
UpdateText(realCell, entryCell);
else if (e.PropertyName == EntryCell.PlaceholderProperty.PropertyName)
UpdatePlaceholder(realCell, entryCell);
else if (e.PropertyName == EntryCell.LabelColorProperty.PropertyName)
UpdateLabelColor(realCell, entryCell);
}
private static void UpdateLabel(CellView cell, EntryCell entryCell)
{
cell.TextLabel.Text = entryCell.Label ?? string.Empty;
}
private static void UpdateLabelColor(CellView cell, EntryCell entryCell)
{
cell.TextLabel.Style.Color = entryCell.LabelColor.ToOouiColor();
}
private static void UpdatePlaceholder(CellView cell, EntryCell entryCell)
{
if (cell.CustomView.FirstChild is TextInput textInput)
textInput.Placeholder = entryCell.Placeholder ?? string.Empty;
}
private static void UpdateText(CellView cell, EntryCell entryCell)
{
if (cell.CustomView.FirstChild is TextInput textInput)
textInput.Text = entryCell.Text ?? string.Empty;
}
private static void OnTextChanged(object sender, EventArgs eventArgs)
{
var textInput = (TextInput)sender;
CellView realCell = GetRealCell(_cell);
if (realCell != null)
((EntryCell)realCell.Cell).Text = textInput.Text;
}
}
}

View File

@ -0,0 +1,66 @@
using Ooui.Forms.Renderers;
using System.ComponentModel;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Internals;
namespace Ooui.Forms.Cells
{
public class ImageCellRenderer : TextCellRenderer
{
public override CellView GetCell(Cell item, CellView reusableView, List listView)
{
var nativeImageCell = reusableView as CellView ?? new CellView();
var result = (CellView)base.GetCell(item, nativeImageCell, listView);
var imageCell = (ImageCell)item;
WireUpForceUpdateSizeRequested(item, result);
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
SetImage(imageCell, result);
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
return result;
}
protected override async void HandlePropertyChanged(object sender, PropertyChangedEventArgs args)
{
var tvc = (CellView)sender;
var imageCell = (ImageCell)tvc.Cell;
base.HandlePropertyChanged(sender, args);
if (args.PropertyName == ImageCell.ImageSourceProperty.PropertyName)
await SetImage(imageCell, tvc);
}
static async Task SetImage(ImageCell cell, CellView target)
{
var source = cell.ImageSource;
target.ImageView.Source = null;
IImageSourceHandler handler;
if (source != null && (handler =
Registrar.Registered.GetHandler<Renderers.IImageSourceHandler>(source.GetType())) != null)
{
string image;
try
{
image = await handler.LoadImageAsync(source).ConfigureAwait(false);
}
catch (TaskCanceledException)
{
image = null;
}
target.ImageView.Source = image;
}
else
target.ImageView.Source = null;
}
}
}

View File

@ -0,0 +1,79 @@
using System;
using System.ComponentModel;
using Xamarin.Forms;
namespace Ooui.Forms.Cells
{
public class SwitchCellRenderer : CellRenderer
{
private static Cell _cell;
public override CellView GetCell(Cell item, CellView reusableView, List listView)
{
var nativeSwitchCell = reusableView as CellView;
Input oouiSwitch = null;
if (nativeSwitchCell == null)
nativeSwitchCell = new CellView();
else
{
oouiSwitch = nativeSwitchCell.CustomView.FirstChild as Input;
if (oouiSwitch != null)
{
nativeSwitchCell.CustomView.RemoveChild(oouiSwitch);
oouiSwitch.Click -= OnSwitchClick;
}
nativeSwitchCell.Cell.PropertyChanged -= OnCellPropertyChanged;
}
SetRealCell(item, nativeSwitchCell);
if (oouiSwitch == null)
{
oouiSwitch = new Input(InputType.Checkbox);
oouiSwitch.SetAttribute("data-toggle", "toggle");
}
var switchCell = (SwitchCell)item;
nativeSwitchCell.Cell = item;
nativeSwitchCell.SecondCol.Style.Width = "25%";
_cell = nativeSwitchCell.Cell;
nativeSwitchCell.Cell.PropertyChanged += OnCellPropertyChanged;
nativeSwitchCell.CustomView.AppendChild(oouiSwitch);
nativeSwitchCell.TextLabel.Text = switchCell.Text ?? string.Empty;
oouiSwitch.IsChecked = switchCell.On;
oouiSwitch.Click += OnSwitchClick;
WireUpForceUpdateSizeRequested(item, nativeSwitchCell);
UpdateBackground(nativeSwitchCell, item);
return nativeSwitchCell;
}
private void OnCellPropertyChanged(object sender, PropertyChangedEventArgs e)
{
var switchCell = (SwitchCell)sender;
var nativeSwitchCell = (CellView)GetRealCell(switchCell);
if (e.PropertyName == SwitchCell.OnProperty.PropertyName)
((Input)nativeSwitchCell.CustomView.FirstChild).IsChecked = switchCell.On;
else if (e.PropertyName == SwitchCell.TextProperty.PropertyName)
nativeSwitchCell.TextLabel.Text = switchCell.Text ?? string.Empty;
}
private void OnSwitchClick(object sender, EventArgs eventArgs)
{
var switchInput = (Input)sender;
CellView realCell = GetRealCell(_cell);
if (realCell != null)
((SwitchCell)realCell.Cell).On = switchInput.IsChecked;
}
}
}

View File

@ -0,0 +1,48 @@
using Ooui.Forms.Extensions;
using System.ComponentModel;
using Xamarin.Forms;
namespace Ooui.Forms.Cells
{
public class TextCellRenderer : CellRenderer
{
public override CellView GetCell(Cell item, CellView reusableView, List listView)
{
var nativeTextCell = base.GetCell(item, reusableView, listView);
var textCell = (TextCell)item;
if (nativeTextCell.Cell != null)
nativeTextCell.Cell.PropertyChanged -= nativeTextCell.HandlePropertyChanged;
nativeTextCell.Cell = textCell;
textCell.PropertyChanged += nativeTextCell.HandlePropertyChanged;
nativeTextCell.PropertyChanged = HandlePropertyChanged;
nativeTextCell.TextLabel.Text = textCell.Text ?? string.Empty;
nativeTextCell.DetailTextLabel.Text = textCell.Detail ?? string.Empty;
nativeTextCell.TextLabel.Style.Color = textCell.TextColor.ToOouiColor();
nativeTextCell.DetailTextLabel.Style.Color = textCell.DetailColor.ToOouiColor();
WireUpForceUpdateSizeRequested(item, nativeTextCell);
UpdateBackground(nativeTextCell, item);
return nativeTextCell;
}
protected virtual void HandlePropertyChanged(object sender, PropertyChangedEventArgs args)
{
var tvc = (CellView)sender;
var textCell = (TextCell)tvc.Cell;
if (args.PropertyName == TextCell.TextProperty.PropertyName)
tvc.TextLabel.Text = textCell.Text ?? string.Empty;
else if (args.PropertyName == TextCell.DetailProperty.PropertyName)
tvc.DetailTextLabel.Text = textCell.Detail ?? string.Empty;
else if (args.PropertyName == TextCell.TextColorProperty.PropertyName)
tvc.TextLabel.Style.Color = textCell.TextColor.ToOouiColor();
else if (args.PropertyName == TextCell.DetailColorProperty.PropertyName)
tvc.DetailTextLabel.Style.Color = textCell.DetailColor.ToOouiColor();
}
}
}

View File

@ -0,0 +1,25 @@
using Xamarin.Forms;
namespace Ooui.Forms.Cells
{
public class ViewCellRenderer : CellRenderer
{
public override CellView GetCell(Cell item, CellView reusableView, List listView)
{
var viewCell = (ViewCell)item;
var nativeViewCell = reusableView as ViewCellView;
if (nativeViewCell == null)
nativeViewCell = new ViewCellView();
nativeViewCell.ViewCell = viewCell;
SetRealCell(item, nativeViewCell);
WireUpForceUpdateSizeRequested(item, nativeViewCell);
return nativeViewCell;
}
}
}

View File

@ -0,0 +1,63 @@
using Ooui.Forms.Renderers;
using System;
using Xamarin.Forms;
namespace Ooui.Forms.Cells
{
public class ViewCellView : CellView
{
private WeakReference<IVisualElementRenderer> _rendererRef;
private ViewCell _viewCell;
public ViewCell ViewCell
{
get { return _viewCell; }
set
{
if (_viewCell == value)
return;
UpdateCell(value);
}
}
private void UpdateCell(ViewCell cell)
{
if (_viewCell != null)
Device.BeginInvokeOnMainThread(_viewCell.SendDisappearing);
_viewCell = cell;
Device.BeginInvokeOnMainThread(_viewCell.SendAppearing);
IVisualElementRenderer renderer;
if (_rendererRef == null || !_rendererRef.TryGetTarget(out renderer))
renderer = GetNewRenderer();
else
{
if (renderer.Element != null && renderer == Platform.GetRenderer(renderer.Element))
renderer.Element.ClearValue(Platform.RendererProperty);
var type = Xamarin.Forms.Internals.Registrar.Registered.GetHandlerType(_viewCell.View.GetType());
var reflectableType = renderer as System.Reflection.IReflectableType;
var rendererType = reflectableType != null ? reflectableType.GetTypeInfo().AsType() : renderer.GetType();
if (rendererType == type || (renderer is DefaultRenderer && type == null))
renderer.SetElement(_viewCell.View);
else
{
renderer = GetNewRenderer();
}
}
Platform.SetRenderer(_viewCell.View, renderer);
}
private IVisualElementRenderer GetNewRenderer()
{
var newRenderer = Platform.CreateRenderer(_viewCell.View);
_rendererRef = new WeakReference<IVisualElementRenderer>(newRenderer);
AppendChild(newRenderer.NativeView);
return newRenderer;
}
}
}

View File

@ -1,5 +1,6 @@
using System;
using Ooui.Forms;
using Ooui.Forms.Cells;
using Ooui.Forms.Renderers;
using Xamarin.Forms;
@ -15,6 +16,7 @@ using Xamarin.Forms;
[assembly: ExportRenderer (typeof (Label), typeof (LabelRenderer))]
[assembly: ExportRenderer (typeof (LinkLabel), typeof (LinkLabelRenderer))]
[assembly: ExportRenderer (typeof (LinkView), typeof (LinkViewRenderer))]
[assembly: ExportRenderer(typeof(ListView), typeof(ListViewRenderer))]
[assembly: ExportRenderer (typeof (ProgressBar), typeof (ProgressBarRenderer))]
[assembly: ExportRenderer (typeof (SearchBar), typeof (SearchBarRenderer))]
[assembly: ExportRenderer(typeof(Slider), typeof(SliderRenderer))]
@ -23,7 +25,12 @@ using Xamarin.Forms;
[assembly: ExportImageSourceHandler (typeof (FileImageSource), typeof (FileImageSourceHandler))]
[assembly: ExportImageSourceHandler (typeof (StreamImageSource), typeof (StreamImagesourceHandler))]
[assembly: ExportImageSourceHandler (typeof (UriImageSource), typeof (ImageLoaderSourceHandler))]
[assembly: ExportCell(typeof(Cell), typeof(CellRenderer))]
[assembly: ExportCell(typeof(EntryCell), typeof(EntryCellRenderer))]
[assembly: ExportCell(typeof(ImageCell), typeof(ImageCellRenderer))]
[assembly: ExportCell(typeof(SwitchCell), typeof(SwitchCellRenderer))]
[assembly: ExportCell(typeof(TextCell), typeof(TextCellRenderer))]
[assembly: ExportCell(typeof(ViewCell), typeof(ViewCellRenderer))]
namespace Ooui.Forms
{
[AttributeUsage (AttributeTargets.Assembly, AllowMultiple = true)]
@ -35,6 +42,14 @@ namespace Ooui.Forms
}
}
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class ExportCellAttribute : HandlerAttribute
{
public ExportCellAttribute(Type handler, Type target) : base(handler, target)
{
}
}
[AttributeUsage (AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class ExportImageSourceHandlerAttribute : HandlerAttribute
{

View File

@ -30,7 +30,7 @@ namespace Xamarin.Forms
Registrar.RegisterAll (new[] {
typeof(ExportRendererAttribute),
//typeof(ExportCellAttribute),
typeof(ExportCellAttribute),
typeof(ExportImageSourceHandlerAttribute),
});
}

View File

@ -0,0 +1,112 @@
using Ooui.Forms.Extensions;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Xamarin.Forms;
using Xamarin.Forms.Internals;
namespace Ooui.Forms.Renderers
{
public class ListViewRenderer : ViewRenderer<ListView, List>
{
private bool _disposed;
private List _listView;
private List<ListItem> _cells;
public ListViewRenderer()
{
_cells = new List<ListItem>();
}
ITemplatedItemsView<Cell> TemplatedItemsView => Element;
protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
{
if (e.NewElement != null)
{
if (Control == null)
{
_listView = new List();
SetNativeControl(_listView);
}
UpdateItems();
UpdateBackgroundColor();
}
base.OnElementChanged(e);
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == ListView.ItemsSourceProperty.PropertyName)
UpdateItems();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing && !_disposed)
{
_disposed = true;
}
}
private void UpdateItems()
{
_cells.Clear();
var items = TemplatedItemsView.TemplatedItems;
if (!items.Any())
{
return;
}
bool grouping = Element.IsGroupingEnabled;
if (grouping)
{
return;
}
foreach (var item in items)
{
var cell = GetCell(item);
var listItem = new ListItem();
listItem.Style["list-style-type"] = "none";
listItem.AppendChild(cell);
_cells.Add(listItem);
}
foreach (var cell in _cells)
{
_listView.AppendChild(cell);
}
}
private void UpdateBackgroundColor()
{
var backgroundColor = Element.BackgroundColor.ToOouiColor();
_listView.Style.BackgroundColor = backgroundColor;
}
private Div GetCell(Cell cell)
{
var renderer =
(Cells.CellRenderer)Registrar.Registered.GetHandler<IRegisterable>(cell.GetType());
var realCell = renderer.GetCell(cell, null, _listView);
return realCell;
}
}
}

136
Samples/ListViewSample.cs Normal file
View File

@ -0,0 +1,136 @@
using Ooui;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Xamarin.Forms;
namespace Samples
{
public class Light : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _name;
private string _comment;
private Xamarin.Forms.Color _color;
private bool _isOn;
public string Name { get { return _name; } set { OnPropertyChanged(); _name = value; } }
public string Comment { get { return _comment; } set { OnPropertyChanged(); _comment = value; } }
public Xamarin.Forms.Color Color { get { return _color; } set { OnPropertyChanged(); _color = value; } }
public bool IsOn { get { return _isOn; } set { OnPropertyChanged(); OnPropertyChanged("isNotOn"); _isOn = value; } }
public bool IsNotOn { get { return !_isOn; } }
public Light()
{
this.IsOn = false;
this.Name = "My first light!";
this.Color = Xamarin.Forms.Color.Blue;
this.Comment = "Bedroom";
}
public Light(bool isOn, string name, Xamarin.Forms.Color color, string comment)
{
this.IsOn = isOn;
this.Name = name;
this.Color = color;
this.Comment = comment;
}
void OnPropertyChanged([CallerMemberName] string propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public static class DataSource
{
public static ObservableCollection<Light> GetLights()
{
ObservableCollection<Light> lights = new ObservableCollection<Light>()
{
new Light(false, "Bedside", Xamarin.Forms.Color.Blue, "Mel's Bedroom"),
new Light(false, "Desk", Xamarin.Forms.Color.Red, "Mel's Bedroom"),
new Light(true, "Flood Lamp", Xamarin.Forms.Color.Olive, "Outside"),
new Light(false, "hallway1", Xamarin.Forms.Color.Teal, "Entry Hallway"),
new Light(false, "hallway2", Xamarin.Forms.Color.Purple, "Entry Hallway")
};
return lights;
}
}
class EntryListViewSample : ISample
{
public string Title => "Xamarin.Forms Basic Entry ListView Sample";
public Ooui.Element CreateElement()
{
var panel = new StackLayout();
var titleLabel = new Xamarin.Forms.Label
{
Text = "ListView",
FontSize = 24,
FontAttributes = FontAttributes.Bold
};
panel.Children.Add(titleLabel);
ListView listView = new ListView() { ItemsSource = DataSource.GetLights() };
listView.ItemTemplate = new DataTemplate(typeof(EntryCell));
listView.ItemTemplate.SetBinding(EntryCell.LabelProperty, "Comment");
listView.ItemTemplate.SetBinding(EntryCell.TextProperty, "Name");
panel.Children.Add(listView);
var page = new ContentPage
{
Content = panel
};
return page.GetOouiElement();
}
public void Publish()
{
UI.Publish("/entry-listview", CreateElement);
}
}
class SwitchListViewSample : ISample
{
public string Title => "Xamarin.Forms Basic Switch ListView Sample";
public Ooui.Element CreateElement()
{
var panel = new StackLayout();
var titleLabel = new Xamarin.Forms.Label
{
Text = "ListView",
FontSize = 24,
FontAttributes = FontAttributes.Bold
};
panel.Children.Add(titleLabel);
ListView listView = new ListView() { ItemsSource = DataSource.GetLights() };
listView.ItemTemplate = new DataTemplate(typeof(SwitchCell));
listView.ItemTemplate.SetBinding(SwitchCell.TextProperty, "Name");
listView.ItemTemplate.SetBinding(SwitchCell.OnProperty, "IsOn");
panel.Children.Add(listView);
var page = new ContentPage
{
Content = panel
};
return page.GetOouiElement();
}
public void Publish()
{
UI.Publish("/switch-listview", CreateElement);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

13
Samples/Monkeys/Monkey.cs Normal file
View File

@ -0,0 +1,13 @@
using Xamarin.Forms;
namespace Monkeys.Models
{
public class Monkey
{
public string Name { get; set; }
public string Location { get; set; }
public string Details { get; set; }
public ImageSource Image { get; set; }
}
}

View File

@ -0,0 +1,60 @@
using System.Collections.ObjectModel;
using Monkeys.Models;
using Xamarin.Forms;
namespace Monkeys.Helpers
{
public static class MonkeyHelper
{
public static ObservableCollection<Monkey> Monkeys { get; set; }
static MonkeyHelper()
{
Monkeys = new ObservableCollection<Monkey>
{
new Monkey
{
Name = "Baboon",
Location = "Africa & Asia",
Details = "Baboons are African and Arabian Old World monkeys belonging to the genus Papio, part of the subfamily Cercopithecinae.",
Image = ImageSource.FromResource("Samples.Monkeys.Images.Baboon.jpg", System.Reflection.Assembly.GetCallingAssembly())
},
new Monkey
{
Name = "Capuchin Monkey",
Location = "Central & South America",
Details = "The capuchin monkeys are New World monkeys of the subfamily Cebinae. Prior to 2011, the subfamily contained only a single genus, Cebus.",
Image = ImageSource.FromResource("Samples.Monkeys.Images.Capuchin.jpg", System.Reflection.Assembly.GetCallingAssembly())
},
new Monkey
{
Name = "Blue Monkey",
Location = "Central and East Africa",
Details = "The blue monkey or diademed monkey is a species of Old World monkey native to Central and East Africa, ranging from the upper Congo River basin east to the East African Rift and south to northern Angola and Zambia",
Image = ImageSource.FromResource("Samples.Monkeys.Images.BlueMonkey.jpg", System.Reflection.Assembly.GetCallingAssembly())
},
new Monkey
{
Name = "Squirrel Monkey",
Location = "Central & South America",
Details = "The squirrel monkeys are the New World monkeys of the genus Saimiri. They are the only genus in the subfamily Saimirinae. The name of the genus Saimiri is of Tupi origin, and was also used as an English name by early researchers.",
Image = ImageSource.FromResource("Samples.Monkeys.Images.Squirrel.jpg", System.Reflection.Assembly.GetCallingAssembly())
},
new Monkey
{
Name = "Golden Lion Tamarin",
Location = "Brazil",
Details = "The golden lion tamarin also known as the golden marmoset, is a small New World monkey of the family Callitrichidae.",
Image = ImageSource.FromResource("Samples.Monkeys.Images.GoldenLionTamarin.jpg", System.Reflection.Assembly.GetCallingAssembly())
},
new Monkey
{
Name = "Howler Monkey",
Location = "South America",
Details = "Howler monkeys are among the largest of the New World monkeys. Fifteen species are currently recognised. Previously classified in the family Cebidae, they are now placed in the family Atelidae.",
Image = ImageSource.FromResource("Samples.Monkeys.Images.Howler.jpg", System.Reflection.Assembly.GetCallingAssembly())
}
};
}
}
}

View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Monkeys.Views.MonkeysView"
Title="Monkeys">
<ContentPage.Content>
<StackLayout>
<Label
Text="ListView"
FontSize="32"
Margin="12, 0"/>
<ListView
ItemsSource="{Binding Monkeys}"
HasUnevenRows="true">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid
Padding="10"
RowSpacing="10"
ColumnSpacing="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image
HeightRequest="66"
Aspect="AspectFill"
WidthRequest="66"
Grid.RowSpan="2"
Source="{Binding Image}"/>
<Label
Grid.Column="1"
Text="{Binding Name}"
FontSize="24"
VerticalOptions="End"/>
<Label
Grid.Column="1"
Grid.Row="1"
VerticalOptions="Start"
Text="{Binding Location}"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>

View File

@ -0,0 +1,15 @@
using Monkeys.ViewModels;
using Xamarin.Forms;
namespace Monkeys.Views
{
public partial class MonkeysView : ContentPage
{
public MonkeysView()
{
InitializeComponent();
BindingContext = new MonkeysViewModel();
}
}
}

View File

@ -0,0 +1,16 @@
using Monkeys.Helpers;
using Monkeys.Models;
using System.Collections.ObjectModel;
namespace Monkeys.ViewModels
{
public class MonkeysViewModel
{
public ObservableCollection<Monkey> Monkeys { get; set; }
public MonkeysViewModel()
{
Monkeys = MonkeyHelper.Monkeys;
}
}
}

24
Samples/MonkeysSample.cs Normal file
View File

@ -0,0 +1,24 @@
using Ooui;
using System;
using System.Collections.Generic;
using System.Text;
using Xamarin.Forms;
namespace Samples
{
public class MonkeysSample : ISample
{
public string Title => "Xamarin.Forms Monkeys";
public Ooui.Element CreateElement()
{
var page = new Monkeys.Views.MonkeysView();
return page.GetOouiElement();
}
public void Publish()
{
UI.Publish("/monkeys", CreateElement);
}
}
}

View File

@ -25,6 +25,7 @@ namespace Samples
}
}
new EntryListViewSample().Publish();
new ButtonSample ().Publish ();
new TodoSample ().Publish ();
new DrawSample ().Publish ();
@ -32,8 +33,10 @@ namespace Samples
new DisplayAlertSample ().Publish ();
new DotMatrixClockSample().Publish();
new EditorSample().Publish();
new MonkeysSample().Publish();
new SearchBarSample().Publish();
new SliderSample().Publish();
new SwitchListViewSample().Publish();
new TimePickerSample().Publish();
new TipCalcSample().Publish();
new WeatherAppSample().Publish();

View File

@ -17,6 +17,12 @@
<EmbeddedResource Include="**/*.xaml" />
<EmbeddedResource Include="BugSweeper\Images\RedBug.png" />
<EmbeddedResource Include="BugSweeper\Images\Xamarin120.png" />
<EmbeddedResource Include="Monkeys\Images\Baboon.jpg" />
<EmbeddedResource Include="Monkeys\Images\BlueMonkey.jpg" />
<EmbeddedResource Include="Monkeys\Images\Capuchin.jpg" />
<EmbeddedResource Include="Monkeys\Images\GoldenLionTamarin.jpg" />
<EmbeddedResource Include="Monkeys\Images\Howler.jpg" />
<EmbeddedResource Include="Monkeys\Images\Squirrel.jpg" />
</ItemGroup>
<ItemGroup>
@ -41,6 +47,9 @@
<EmbeddedResource Update="DotMatrixClock\DotMatrixClockPage.xaml">
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Monkeys\MonkeysView.xaml">
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
<EmbeddedResource Update="TipCalc\TipCalcPage.xaml">
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
@ -56,6 +65,13 @@
<None Remove="BugSweeper\Images\RedBug.png" />
<None Remove="BugSweeper\Images\Xamarin120.png" />
<None Remove="DotMatrixClock\DotMatrixClockPage.xaml" />
<None Remove="Monkeys\Images\Baboon.jpg" />
<None Remove="Monkeys\Images\BlueMonkey.jpg" />
<None Remove="Monkeys\Images\Capuchin.jpg" />
<None Remove="Monkeys\Images\GoldenLionTamarin.jpg" />
<None Remove="Monkeys\Images\Howler.jpg" />
<None Remove="Monkeys\Images\Squirrel.jpg" />
<None Remove="Monkeys\MonkeysView.xaml" />
<None Remove="TipCalc\TipCalcPage.xaml" />
<None Remove="WeatherApp\WeatherPage.xaml" />
</ItemGroup>