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);
});