우선 서버 만들기는 아래 포스팅을 참고한다.

2017/11/27 - [C#.NET/C#] - 카카오 쳇봇 만들기 - 2 (C# 서버 만들기)

2017/11/27 - [C#.NET/C#] - 카카오 쳇봇 만들기 - 3 (C# 서버 만들기)

 

서버쪽 코드

        #region PostUpLoadImage
        [Route("api/Files/Upload")]
        public async Task<string> PostUpLoadImage()
        {
            try
            {
                var httpRequest = HttpContext.Current.Request;

                if (httpRequest.Files.Count > 0)
                {
                    foreach (string file in httpRequest.Files)
                    {
                        var postedFile = httpRequest.Files[file];

                        var fileName = postedFile.FileName.Split('\\').LastOrDefault().Split('/').LastOrDefault();

                        var filePath = HttpContext.Current.Server.MapPath("~/Uploads/" + fileName);

                        postedFile.SaveAs(filePath);

                        return "/Uploads/" + fileName;
                    }
                }
            }
            catch (Exception exception)
            {
                return exception.Message;
            }

            return "no files";
        }
        #endregion

 

Xamarin Forms

Nuget 에서 Xam.Plugin.Media 설치

 

xaml 코드

<?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="MiGong.TestPage">
    <ContentPage.Content>
        <StackLayout>
            <Label Text="File Upload"
           HorizontalOptions="Center" TextColor="Black" FontSize="20"/>

            <Button Text="Pick Photo"
            BackgroundColor="Teal" TextColor="White" FontSize="20" Clicked="PickPhoto_Clicked"/>

            <Button Text="Take Photo"
            BackgroundColor="Navy" TextColor="White" FontSize="20" Clicked="TakePhoto_Clicked"/>

            <Image x:Name="FileImage" WidthRequest="400" HeightRequest="220"/>

            <Label x:Name="LocalPathLabel" TextColor="Black" FontSize="18"/>

            <Button Text="Upload Photo"
            BackgroundColor="Purple" TextColor="White" FontSize="20" Clicked="UploadFile_Clicked"/>

            <Label x:Name="RemotePathLabel" FontSize="20" TextColor="Black"/>

        </StackLayout>
    </ContentPage.Content>
</ContentPage>

xaml.cs 코드 - 동작은 간단하다 파일을 선택하거나 카메라를 찍어서 서버에 해당 파일을 업로드한다.

[XamlCompilation(XamlCompilationOptions.Compile)]
 public partial class TestPage : ContentPage
 {
        private MediaFile _mediaFile;

        public TestPage ()
  {
   InitializeComponent ();
  }

        private async void PickPhoto_Clicked(object sender, EventArgs e)
        {
            await CrossMedia.Current.Initialize();

            if (!CrossMedia.Current.IsPickPhotoSupported)
            {
                await DisplayAlert("No PickPhoto", ":( No PickPhoto available.", "OK");
                return;
            }

            _mediaFile = await CrossMedia.Current.PickPhotoAsync();

            if (_mediaFile == null)
                return;

            LocalPathLabel.Text = _mediaFile.Path;

            FileImage.Source = ImageSource.FromStream(() =>
            {
                return _mediaFile.GetStream();
            });
        }

        private async void TakePhoto_Clicked(object sender, EventArgs e)
        {
            await CrossMedia.Current.Initialize();

            if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
            {
                await DisplayAlert("No Camera", ":( No camera available.", "OK");
                return;
            }

            _mediaFile = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
            {
                Directory = "Sample",
                Name = "myImage.jpg"
            });

            if (_mediaFile == null)
                return;

            LocalPathLabel.Text = _mediaFile.Path;

            FileImage.Source = ImageSource.FromStream(() =>
            {
                return _mediaFile.GetStream();
            });
        }

        private async void UploadFile_Clicked(object sender, EventArgs e)
        {
            var content = new MultipartFormDataContent();

            content.Add(new StreamContent(_mediaFile.GetStream()),
                "\"file\"",
                $"\"{_mediaFile.Path}\"");

            var httpClient = new HttpClient();

            var uploadServiceBaseAddress = "http://localhost:12214/api/Files/Upload";

            var httpResponseMessage = await httpClient.PostAsync(uploadServiceBaseAddress, content);

            RemotePathLabel.Text = await httpResponseMessage.Content.ReadAsStringAsync();
        }
    }

안드로이드쪽 MainActivity.cs 의 아래 굵은 부분 코딩 추가

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        protected override void OnCreate(Bundle bundle)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(bundle);

            CrossCurrentActivity.Current.Init(this, bundle);

            global::Xamarin.Forms.Forms.Init(this, bundle);
            LoadApplication(new App());
        }

        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
        {
            Plugin.Permissions.PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }

    }

AssemblyInfo.cs 파일에 아래 코드 추가

[assembly: UsesFeature("android.hardware.camera", Required = false)]
[assembly: UsesFeature("android.hardware.camera.autofocus", Required = false)]

매니패스트 권한을 부여한다.

 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 <uses-permission android:name="android.permission.CAMERA" />

서버쪽에 사이트 루트에 Uploads 폴더를 만든다.

위 까지 하면 파일 선택하여 업로드가 가능하다.

카메라를 사용하려면 좀더 설정이 필요하다.

AndroidManifest.xml 에 아래 내용추가

 <application ...">
    <provider android:name="android.support.v4.content.FileProvider"
          android:authorities="${applicationId}.fileprovider"
          android:exported="false"
          android:grantUriPermissions="true">

      <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"></meta-data>
    </provider>
  </application>

안드로이드 쪽 프로젝트에 아래 처럼 Resources 폴더 밑에 xml 폴더를 만들고 file_paths.xml  을 만들고

 

내용은 아래처럼 작성

<?xml version="1.0" encoding="utf-8" ?>
  <paths xmlns:android="http://schemas.android.com/apk/res/android">
<!--
    <external-path name="my_images" path="Android/data/com.example.package.name/files/Pictures" />
    <external-path name="my_movies" path="Android/data/com.example.package.name/files/Movies" />
-->
   
    <external-files-path name="my_images" path="Pictures" />
    <external-files-path name="my_movies" path="Movies" />
  </paths>

 

추가 자세한 사항은 아래 링크를 참고

https://github.com/jamesmontemagno/MediaPlugin

 

이미지 표현시 아래 처럼 에러가 발생되었다.

Failed to allocate a 88542732 byte allocation with 16768576 free bytes and 70MB until OOM

이미지 크기가 width 1440 , height 2560 을 넘으면 이런 에러가 발생된다고 한다.

이미지 크기를 조절하니 에러가 바로 사라졌다.

Xamarin Forms 에서

푸쉬알림을 Firebase, App Center 를 이용해서 처리하는 방법을 간략히 정리해봅니다.

1. Firebase 가입

https://firebase.google.com/ 가입 후 (구글 및 다른 계정으로도 로그인 가능)

https://console.firebase.google.com/ 로 이동하여 프로젝트 추가

Android 앱에 Firebase 추가 선택

안드로이드 프로젝트의 패키지명 기입 후 앱등록 이후 2,3 단계는 그냥 확인.

좌측 상단의 톱니바퀴 선택 후 프로젝트 설정으로 이동하고

클라우드 메시징 탭을 선택.

위그림과 같이 Server Key 와 SenderId 정보를 기억.

 

2. Xamarin Forms 프로젝트 구성 (.Net Standard)

 

 

3. Nuget 에서 Microsoft.AppCenter.Push 설치

 

4. App Center 가입

https://appcenter.ms 사이트로 이동하여 가입 (마이크로소프트 계정 및 구글, 페이스북 으로 로그인 가능)

App 만들기 하여 아래 그림과 같이 Android 와 Xamarin 을 선택 하여 이름 지정 후 생성

Push 를 선택하고 가이드에 따라 코딩.


AndroidManifest.xml 파일에 아래 내용  추가
<permission android:protectionLevel="signature"android:name="${applicationId}.permission.C2D_MESSAGE" />
<uses-permissionandroid:name="${applicationId}.permission.C2D_MESSAGE" />

${applicationId} 은 패키지명으로 변경 해야함.


안드로이드인 경우 아래 처럼
Push.SetSenderId("{SenderId}");
AppCenter.Start("282b7f5d-18b4-4e26-8920-8414d6df405b", typeof(Push));

Xamarin Forms 인 경우 아래 처럼 코딩
Push.SetSenderId("{SenderId}");
LoadApplication(new App());

SenderId 는 1번에서 기억해 놓은 senderID 를 이용

▼ Firebase 의 Server Key 기입

 

5. 추가 프로젝트 설정

안드로이드에서 permission 을 INTERNET 도 주어야 함

AndroidManifest.xml 파일에 아래 내용  추가

<uses-permission android:name="android.permission.INTERNET" />

 

 

참고링크

https://docs.microsoft.com/en-us/appcenter/sdk/push/xamarin-android

 

다른 방법

https://onesignal.com 을 통해서도 처리 가능

=> https://www.youtube.com/watch?v=EPIrNxuwAj8&t=851s
=> https://documentation.onesignal.com/docs/xamarin-sdk-setup

이번시간에는 Picker 와 WebView 컨트롤을 알아보겠습니다.

(추가로 DisplayActionSheet 메서드 사용법도 알아볼께요)

 

Picker 는 윈폼으로 말하면 ComboBox 와 같은 형태로 여러 항목중에 하나를 선택할수 있는 컨트롤입니다.

https://developer.xamarin.com/api/type/Xamarin.Forms.Picker/

 

WebView 는 컨트롤 명에서도 유추할수 있듯이 웹페이지를 보는 컨트롤입니다.

WebView 에 url 을 넣어도 되지만 직접 html 코딩을 넣을수도 있습니다.

반드시 Android 에서 실행할때는 INTERNET 권한을 줘야합니다.

https://developer.xamarin.com/guides/xamarin-forms/user-interface/webview/

 

위 두 컨트롤의 예시 입니다.

WebPickerPage.xaml

<?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="XamarinFormsStudy.WebPickerPage">
    <ContentPage.Content>
        <StackLayout>
            <Label Text="Picker"/>
            <Picker x:Name="picker" SelectedIndexChanged="picker_SelectedIndexChanged"/>
            <Button x:Name="button" Text="DisplayActionSheet" Clicked="button_Clicked"/>
            <Label Text="WebView"/>
            <WebView x:Name="webView" VerticalOptions="FillAndExpand"/>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

WebPickerPage.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace XamarinFormsStudy
{
 [XamlCompilation(XamlCompilationOptions.Compile)]
 public partial class WebPickerPage : ContentPage
 {
  public WebPickerPage()
  {
   InitializeComponent ();

            this.Padding = new Thickness(10, Device.OnPlatform(40, 20, 20), 10, 5);

            // Picker 에 데이터를 Add 합니다.
            this.picker.Items.Add("Easy");
            this.picker.Items.Add("Normal");
            this.picker.Items.Add("Hard");


            this.webView.Source = new UrlWebViewSource { Url = "http://m.naver.com" };
        }

        private void picker_SelectedIndexChanged(object sender, EventArgs e)
        {
            // 선택한 항목을 팝업으로 띄워줍니다.
            string selectData = this.picker.Items[this.picker.SelectedIndex];
            DisplayAlert(selectData, "SelectValue", "OK");
        }

        private async void button_Clicked(object sender, EventArgs e)
        {
            // 선택 팝업이 뜨고 선택한 항목에 따라 버튼 색을 바꿔줍니다.
            string color = await DisplayActionSheet("선택하세요", "취소", "닫기", "BLUE", "YELLOW", "RED", "GREEN");
            switch (color)
            {
                case "BLUE": this.button.BackgroundColor = Color.Blue; break;
                case "YELLOW": this.button.BackgroundColor = Color.Yellow; break;
                case "RED": this.button.BackgroundColor = Color.Red; break;
                case "GREEN": this.button.BackgroundColor = Color.Green; break;
            }
        }
    }
}

결과

Normal 을 선택한 경우

 

추가로 DisplayActionSheet 함수는 목록 데이터를 팝업으로 보여주고 선택할 수 있게 합니다.

선택에 따른 처리도 가능합니다.

* 아래처럼 선택 항목들이 나열되고 선택하게되면 버튼 색이 선택한 색으로 변경됩니다.

 

GitHub > https://github.com/kjundev/XamarinForms

SQLite 다루는 참고 동영상 링크

https://www.youtube.com/watch?v=t3w8HIdBFiA

 

이번 시간에는 DataBase 관련 첫번째 시간으로 SQLite 를 알아보도록 하겠습니다.

보통 서버와 연결하지 않고 로컬로만 어떤 데이터를 다룰 때는 SQLite 가 가장 편한 것 같습니다.

이번에 소개할건 PlugIn.SQLite 입니다. (Nuget 에서 받을수 있습니다.)

 

프로젝트를 열고 솔루션의 NutGet 패키지 관리로 들어갑니다.

PlugIn.SQLite 로 검색하면 아래처럼 하나가 나옵니다.

오른쪽에 모두 체크하고 설치를 클릭합니다.

확인을 하게되면

각각 프로젝트 별로 (UWP 제외) SQLite 폴더가 생성되고 내부에 코딩이 자동으로 들어가 있게됩니다.

각각 프로젝트에 맞게 namespace 등은 변경해 주어야합니다.

[ Android ]

코드 내용 (프로젝트에 맞게 변경이 완료된 내용입니다.)

using System.IO;
using SQLite;
using Xamarin.Forms;
using XamarinFormsStudy.Android;

[assembly: Dependency(typeof(SQLite_Android))]

namespace XamarinFormsStudy.Android
{
    public class SQLite_Android : ISQLite
    {
        public SQLite_Android() { }
        public SQLiteConnection GetConnection()
        {
            var sqliteFilename = "MySQLiteDB.db3";
            string documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal); // Documents folder
            var path = Path.Combine(documentsPath, sqliteFilename);
            // Create the connection
            var conn = new SQLiteConnection(path);
            // Return the database connection
            return conn;
        }
    }
}

[ iOS ]

코드내용 (프로젝트에 맞게 변경이 완료된 내용입니다.)

using System;
using System.IO;
using SQLite;
using Xamarin.Forms;
using XamarinFormsStudy.iOS;

[assembly: Dependency(typeof(SQLite_iOS))]

namespace XamarinFormsStudy.iOS
{
    public class SQLite_iOS : ISQLite
    {

        public SQLite_iOS()
        {
        }

        public SQLiteConnection GetConnection()
        {
            var sqliteFilename = "MySQLiteDB.db3";
            string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); // Documents folder
            string libraryPath = Path.Combine(documentsPath, "..", "Library"); // Library folder
            var path = Path.Combine(libraryPath, sqliteFilename);
            // Create the connection
            var conn = new SQLiteConnection(path);
            // Return the database connection
            return conn;
        }
    }
}

[ UWP ]

UWP 는 참조는 추가 되나 관련 파일이 자동으로 추가되지 않습니다.

수동으로 추가해 주어야합니다.

이식가능 프로젝트에 보면 'SQLite-AppSample' 폴더에 readme.txt 파일이 있는데 여기에 UWP 에 넣어야할 코딩이 나와있습니다.

UWP 프로젝트에서 클래스를 추가하고 위 코딩을 넣습니다.

당연히 프로젝트에 맞에 수정을 해야합니다.

코드 내용 (프로젝트에 맞게 변경이 완료된 내용입니다.)

using System.IO;
using Windows.Storage;
using SQLite;
using Xamarin.Forms;
using XamarinFormsStudy.UWP;

[assembly: Dependency(typeof(SQLite_Uwp))]

namespace XamarinFormsStudy.UWP
{
    public class SQLite_Uwp : ISQLite
    {
        public SQLite_Uwp()
        {
        }

        public SQLiteConnection GetConnection()
        {
            var sqliteFilename = "MySQLiteDB.db3";
            string documentsPath = ApplicationData.Current.LocalFolder.Path;
            var path = Path.Combine(documentsPath, sqliteFilename);
            // Create the connection
            var conn = new SQLiteConnection(path);
            // Return the database connection
            return conn;
        }
    }
}

 

[ 이식가능 프로젝트(PCL) ]

이식가능에 추가된 SQLite 관련된 파일중 TodoItem 은 테스트할 데이터에 대한 테이블의 형태가 정의되어있습니다.

using SQLite;

namespace XamarinFormsStudy
{
    public class TodoItem
    {

        // 키 정보이며 하나씩 증가합니다.
        [PrimaryKey, AutoIncrement]
        public int ID { get; set; }

        public string Text { get; set; }

        public bool Done { get; set; }

        public override string ToString()
        {
            return string.Format("Done : {0}, Text : {1}", Done, Text);
        }
    }
}

그리고 SQLiteSamplePage 에서는 CRUD 관련 코딩 예시가 나와있습니다.

또한 ContentPage 도 제공해 주어 바로 실행하여 확인도 가능합니다.

App.xaml 파일에서 아래 처럼 호출되도록 하고 실행해 보면

MainPage = new SQLiteSamplePage().GetSampleContentPage();

아래 와 같은 결과가 나옵니다.

데이터는 입력항목과 스위치 버튼의 true,false 값이 Add 하면 저장되고 Refresh 하게되면 저장된 값이 아래로 나열됩니다.

 

 

참고

https://www.youtube.com/watch?v=nrXmA-0NoOE&index=26&list=PLpbcUe4chE7-5t2mlamz6yB0qzAfO5Yln

GitHub > https://github.com/knagjun/XamarinForms

 

 

블루투스 참고용 링크

https://github.com/aritchie/bluetoothle

 

ListView 는 데이터를 나열하여 표시해주는 컨트롤입니다.

더이상 설명은 필요 없을것 같으니 바로 시작하겠습니다.

신규 ContentPage 를 생성하여 ListViewPage.xaml 를 만듭니다.

ListViewPage.xaml 디자인 단에 아래 처럼 코딩합니다.

<?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="XamarinFormsStudy.ListViewPage">
    <ListView x:Name="MainListView" HasUnevenRows="True">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout Orientation="Horizontal" Padding="10">
                        <Label Text="{Binding ID}"/>
                        <StackLayout VerticalOptions="Center">
                            <Label Text="{Binding Name}" Font="Large"/>
                            <Label Text="{Binding Age}" />
                            <Label Text="{Binding Dept}" Font="Bold" Opacity="0.6"/>
                            <Label Text="{Binding Desc}" Font="Small"/>
                        </StackLayout>
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ContentPage>

위 내용을 설명하자면 ListView.ItemTemplate 은 리스트뷰에 바인딩될 항목에 대해서 일정한 모양으로 바인딩 될수 있도록 해주는

템플릿을 정의하기 위한 것이라고 보면됩니다.

<DataTemplate> <ViewCell > 의 내부에 데이터가 바인딩될 구조를 미리 정의 하면 데이터가 그 구조에 맞게 바인딩됩니다.

디자인 코드를 보면 ID는 왼쪽 끝으로 위치하고 다른 항목들 (Name,Age등) 은 오른쪽에 위치시켜 아래로 쭉 나열하여 위치시킨 것을 알수 있습니다.

이제 ListViewPage.xaml.cs 파일을 코딩합니다.

(설명은 주석으로..)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace XamarinFormsStudy
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class ListViewPage : ContentPage
    {
        public ListViewPage()
        {
            InitializeComponent();

            //MainListView.ItemsSource = new List<string> { "AA", "BB", "CC" };

            // 데이터들을 정의합니다.
            ListViewTestData data1 = new ListViewTestData() { ID = 1, Name = "user1", Age = 34, Dept = "Povice", Desc = "TestUser1" };
            ListViewTestData data2 = new ListViewTestData() { ID = 2, Name = "user2", Age = 31, Dept = "Povice", Desc = "TestUser2" };
            ListViewTestData data3 = new ListViewTestData() { ID = 3, Name = "user3", Age = 30, Dept = "Povice", Desc = "TestUser3" };
            ListViewTestData data4 = new ListViewTestData() { ID = 4, Name = "user4", Age = 40, Dept = "kjun", Desc = "TestUser4" };

            List<ListViewTestData> testData = new List<ListViewTestData>();
            testData.Add(data1);
            testData.Add(data2);
            testData.Add(data3);
            testData.Add(data4);

            // ListView 의 Source 에 적용하면 디자인 코드의 itemtemplate 에 바인딩될 항목을들 찾아 바인딩됩니다.
            MainListView.ItemsSource = testData;
        }
    }

    /// <summary>
    ///  ListView 에 바인딩될 데이터입니다.
    /// </summary>
    public class ListViewTestData
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
        public string Dept { get; set; }
        public string Desc { get; set; }
    }
}

 

결과는 아래와 같습니다.

 

LisView 는 디자인을 어떻게 하냐에 따라서 정말 달라보입니다.

Styling 하는 방법도 시간이 된다면 포스팅 할 예정입니다.

 

참고

http://blog.naver.com/goldrushing/220668652665

https://developer.xamarin.com/guides/xamarin-forms/user-interface/listview/

https://www.youtube.com/watch?v=N0e3fPisIw8&list=PLpbcUe4chE7-5t2mlamz6yB0qzAfO5Yln&index=9

GitHub > https://github.com/knagjun/XamarinForms

'Xamarin' 카테고리의 다른 글

(Xamarin Forms) 7.SQLite - PlugIn.SQLite  (0) 2017.07.12
(Xamarin Forms) Bluetooth - 링크  (0) 2017.07.11
(Xamarin Forms) 6.ListView  (0) 2017.07.11
(Xamarin Forms) 5.Chart - OxyPlot (Line Chart)  (0) 2017.07.11
(Xamarin Forms) 5.Chart - OxyPlot  (0) 2017.07.10
(Xamarin Forms) 4.Image  (0) 2017.07.06

Image 는 사진이나 그림파일을 보여주도록 하는 컨트롤입니다.

보통 Image 는 각각의 장치 프로젝트 별로 그림 파일이 존재해야하고

그에따라 코딩이 좀 변화가 있어야합니다.

예를들면 아래처럼 각 장치별로 위치가 다르기 때문에 처리가 필요합니다.

beachImage.Source =  Device.OnPlatform(
            iOS: ImageSource.FromFile("Images/waterfront.jpg"),
            Android:  ImageSource.FromFile("waterfront.jpg"),
            WinPhone: ImageSource.FromFile("Images/waterfront.png"));

하지만 저희는 이를 한곳으로 몰아놓고 사용하고 싶기때문에 그 방법을 공유하고자 합니다.

우선 이식가능 프로젝트에 원하는 이미지를 넣습니다.

전 위처럼 3가지 이미지를 넣었습니다.

그리고 각각 이미지를 선택하면 아래 속성에서 빌드 작업이 '내용' 으로 되어있는데 '포함 리소스' 로 변경합니다.

위 작업까지만 하면 코딩단에서는 아래처럼 코드하여 이미지를 각 장치에 상관없이 바인딩 할수 있습니다.

Image image1 = new Image() { Source = ImageSource.FromResource("XamarinFormsStudy.bottom.png") };

하지만 xaml 파일에서도 사용하기 위해서는 추가 작업이 필요합니다.

먼저 클래스를 하나 추가하여 아래처럼 코딩합니다.

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace XamarinFormsStudy
{
    [ContentProperty("Source")]
    public class ImageResourceExtension : IMarkupExtension
    {
        public string Source { get; set; }

        public object ProvideValue(IServiceProvider serviceProvider)
        {
            if (Source == null)
            {
                return null;
            }
           
            var imageSource = ImageSource.FromResource(Source);

            return imageSource;
        }
    }
}

위 내용은 xaml 파일에서 이미지를 가져와서 바인딩 하고자 할때 위 ProvideValue 메서드를 타도록 해줍니다.

xaml 파일에서는 아래처럼 코딩하면 됩니다.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:XamarinFormsStudy;assembly=XamarinFormsStudy"
             x:Class="XamarinFormsStudy.AbsoluteLayoutPage">
    <ContentPage.Content>
        <AbsoluteLayout Padding="15">
            <Image AbsoluteLayout.LayoutFlags="PositionProportional" AbsoluteLayout.LayoutBounds="0.5, 0, 100, 100" Rotation="30" Source="{local:ImageResource XamarinFormsStudy.bottom.png}" />
            <Image AbsoluteLayout.LayoutFlags="PositionProportional" AbsoluteLayout.LayoutBounds="0.5, 0, 100, 100" Rotation="60" Source="{local:ImageResource XamarinFormsStudy.middle.png}" />
            <Image AbsoluteLayout.LayoutFlags="PositionProportional" AbsoluteLayout.LayoutBounds="0.5, 0, 100, 100" Source="{local:ImageResource XamarinFormsStudy.cover.png}" />
        </AbsoluteLayout>
    </ContentPage.Content>
</ContentPage>

>위 내용의 결과

안드로이드

IOS

 

UWP

 

참고

https://developer.xamarin.com/guides/xamarin-forms/user-interface/images/

GitHub > https://github.com/knagjun/XamarinForms

전날까지 잘 실행되던 솔루션이 오늘 빌드를 하니 에러가 발생되었다.

심각도 코드 설명 프로젝트 파일 줄 비표시 오류(Suppression) 상태
오류  "XamlCTask" 작업에서 "DebugType" 매개 변수를 지원하지 않습니다. 해당 매개 변수가 작업에 있는지 그리고 설정 가능한 public 인스턴스 속성인지 확인하세요. XamarinFormsStudy   
오류  해당 입력 매개 변수를 사용하여 "XamlCTask" 작업을 초기화할 수 없습니다. XamarinFormsStudy   
오류  "XamlCTask" 작업에서 "DebugType" 매개 변수를 지원하지 않습니다. 해당 매개 변수가 작업에 있는지 그리고 설정 가능한 public 인스턴스 속성인지 확인하세요. XamarinFormsStudy.Android   
오류  해당 입력 매개 변수를 사용하여 "XamlCTask" 작업을 초기화할 수 없습니다. XamarinFormsStudy.Android 

일단 구글링을 해보니

https://forums.xamarin.com/discussion/54790/the-xamlctask-task-failed-unexpectedly

위 링크에서 솔루션용 NuGet 패키지 관리에서 Xamarin Forms 를 지웠다 다시 깔라는데....

일단 들어가 보았다.

들어가니 아래처럼 업데이트 할 항목이 수두룩했다.

처음에는 Xamarin.Forms 만 업데이트 했으나 여전히 에러가 발생되어 모든 항목을 체크하고 업데이트 진행해 보았다..

비쥬얼스튜디오를 껐다 켜야한다.

재실행하니 에러가 사라졌다!!!

업데이트 하고 되는걸 보니 먼가 버전이 안맞거나 하면 나는 에러로 보인다.

'Xamarin' 카테고리의 다른 글

(Xamarin Forms) 4.Image  (0) 2017.07.06
(Xamarin Forms) Error - ResolveLibraryProjectImports  (0) 2017.07.05
(Xamarin Forms) Error - XamlCTask  (0) 2017.07.05
(Xamarin Forms) 3.Layout  (0) 2017.07.05
(Xamarin Forms) 2.MasterDetailPage  (0) 2017.06.30
(Xamarin Forms) 1.ContentPage  (0) 2017.06.29

+ Recent posts