Crea tu primer aplicación con .NET MAUI

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

Deja un comentario

Tu dirección de correo electrónico no será publicada.