Esta entrada, forma parte del taller impartido en la .NET Conf LATAM 2021, que puedes ver en el siguiente video:
[PENDIENTE]
Requerimientos para realizar el taller de .NET MAUI
Los requerimientos para llevar a cabo el taller son los siguientes:
- Mínimamente, la versión Visual Studio 2022 Versión 17.1.0 Preview 1.0
- Crear una cuenta en la página de la API de imgflip
Snippet 1:
<Grid RowDefinitions=".1*,.9*"> </Grid>
Snippet 2:
<Grid RowDefinitions=".1*,.9*"> <Grid BackgroundColor="{DynamicResource PrimaryColor}"> <Label Text="I Love Memes!" TextColor="White" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" FontSize="Large"/> </Grid> </Grid>
Snippet 3:
<CollectionView Grid.Row="1"> <CollectionView.ItemsSource> <x:Array Type="{x:Type x:String}"> <x:String>mono</x:String> <x:String>monodroid</x:String> <x:String>monotouch</x:String> <x:String>monorail</x:String> <x:String>monodevelop</x:String> <x:String>monotone</x:String> <x:String>monopoly</x:String> <x:String>monomodal</x:String> <x:String>mononucleosis</x:String> </x:Array> </CollectionView.ItemsSource> </CollectionView>
Snippet 4:
<CollectionView.ItemTemplate> <DataTemplate> <Frame Padding="0" HeightRequest="150" WidthRequest="150"> <Image Source="https://i.imgflip.com/1g8my4.jpg" Aspect="Fill" /> </Frame> </DataTemplate> </CollectionView.ItemTemplate>
Snippet 5:
<CollectionView.ItemsLayout> <GridItemsLayout Orientation="Vertical" Span="2" VerticalItemSpacing="5" HorizontalItemSpacing="5"/> </CollectionView.ItemsLayout>
Snippet 6:
public class BaseViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
Snippet 7:
internal class MainPageViewModel : BaseViewModel { }
Snippet 8:
public class MemeData { public bool success { get; set; } public Data data { get; set; } } public class Data { public Meme[] memes { get; set; } } public class Meme { public string id { get; set; } public string name { get; set; } public string url { get; set; } public int width { get; set; } public int height { get; set; } public int box_count { get; set; } }
Snippet 9:
internal class MainPageViewModel : BaseViewModel { HttpClient client = new HttpClient(); private ObservableCollection<Meme> memes; public ObservableCollection<Meme> Memes { get => memes; set { memes = value; OnPropertyChanged(); } } public MainPageViewModel() { Task.Run(async () => { var result = await client.GetStringAsync("https://api.imgflip.com/get_memes"); var collection = JsonConvert.DeserializeObject<MemeData>(result); if (collection.data != null) { Memes = new ObservableCollection<Meme>(collection.data.memes.Where(x=>x.box_count == 2)); } }); } }
Snippet 10:
<CollectionView Grid.Row="1" ItemsSource="{Binding Memes}">
Snippet 11:
<Image Source="{Binding url}" Aspect="Fill" />
Snippet 12:
<ContentPage.Content> <StackLayout> <Entry Placeholder="Text 1" Text="{Binding Text1}"/> <Entry Placeholder="Text 2" Text="{Binding Text2}"/> <Image Source="{Binding CurrentImage}" Margin="15"/> <Button Text="Generate Meme" Command="{Binding GenerateButton}" Margin="15,10,15,0"/> <Button Text="Download Meme" Command="{Binding DownloadButton}" Margin="15,10,15,0"/> </StackLayout> </ContentPage.Content>
Snippet 13:
MainPage = new CreatorPage();
Snippet 14:
private string currentImage = "https://i.imgflip.com/1g8my4.jpg"; public string Text1 { get; set; } public string Text2 { get; set; } public ICommand GenerateButton { get; set; } public ICommand DownloadButton { get; set; } public string CurrentImage { get => currentImage; set { currentImage = value; OnPropertyChanged(); } }
Snippet 15:
public CreatorViewModel() { GenerateButton = new Command(async () => { MultipartFormDataContent multiContent = new MultipartFormDataContent(); multiContent.Headers.ContentType.MediaType = "multipart/form-data"; multiContent.Add(new StringContent("87743020"), "template_id"); multiContent.Add(new StringContent("demos222"), "username"); multiContent.Add(new StringContent("p@ssw0rd123"), "password"); multiContent.Add(new StringContent(Text1), "boxes[0][text]"); multiContent.Add(new StringContent(Text2), "boxes[1][text]"); HttpClient client = new HttpClient(); var response = await client.PostAsync("https://api.imgflip.com/caption_image", multiContent); var responsestr = response.Content.ReadAsStringAsync().Result; }); }
Snippet 16:
MainPage = new NavigationPage(new MainPage());
Snippet 17:
<CollectionView Grid.Row="1" SelectedItem="{Binding CurrentMeme}" ItemsSource="{Binding Memes}" SelectionMode="Single">
Snippet 18:
private Meme currentMeme; public Meme CurrentMeme { get => currentMeme; set { currentMeme = value; } }
Snippet 19:
private INavigation Navigation; public MainPageViewModel(INavigation _navigation) { Navigation = _navigation;
Snippet 20:
public MainPage() { InitializeComponent(); BindingContext = new MainPageViewModel(this.Navigation); }
Snippet 21:
public Meme CurrentMeme { get => currentMeme; set { currentMeme = value; var page = new CreatorPage(currentMeme); Navigation.PushAsync(page); } }
Snippet 22:
public CreatorPage(object data)
Snippet 23:
public CreatorViewModel(object model)
Snippet 24:
var meme = model as Meme; if(meme!=null) { currentImage = meme.url; }
Snippet 25:
GenerateButton = new Command(async () => { MultipartFormDataContent multiContent = new MultipartFormDataContent(); multiContent.Headers.ContentType.MediaType = "multipart/form-data"; multiContent.Add(new StringContent(meme.id), "template_id"); multiContent.Add(new StringContent("demos222"), "username"); multiContent.Add(new StringContent("p@ssw0rd123"), "password"); multiContent.Add(new StringContent(Text1), "boxes[0][text]"); multiContent.Add(new StringContent(Text2), "boxes[1][text]"); HttpClient client = new HttpClient(); var response = await client.PostAsync("https://api.imgflip.com/caption_image", multiContent); var responsestr = response.Content.ReadAsStringAsync().Result; memeResponse = JsonConvert.DeserializeObject<MemeResponse>(responsestr); CurrentImage = memeResponse.data.url; });
Snippet 26:
public class MemeResponse { public bool success { get; set; } public Data data { get; set; } } public class Data { public string url { get; set; } public string page_url { get; set; } }
Snippet 27:
namespace MemauiTests.Models.Response
Snippet 28:
public MemeResponse memeResponse { get; set; }
Snippet 29:
DownloadButton = new Command(async () => { await Browser.OpenAsync(CurrentImage); });