아래는 주문 이력 화면 예시로 

CollectionView 에서 Header 가 있는 경우 처리하는 방법입니다.

        <CollectionView
                x:Name="historyCollectionView"
                Margin="5"
                SelectionMode="Single"
                EmptyView="주문이력이 없습니다."
                SelectionChanged="OnCollectionViewSelectionChanged" >
            <CollectionView.Header>
                <StackLayout>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="90" />
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="70" />
                            <ColumnDefinition Width="70" />
                        </Grid.ColumnDefinitions>
                        <Label Grid.Column="0" Text="주문일자" TextColor="Black" FontSize="15" VerticalTextAlignment="Center" HorizontalTextAlignment="Center"/>
                        <Label Grid.Column="1" Text="주문매장" TextColor="Black" FontSize="15" VerticalTextAlignment="Center" HorizontalTextAlignment="Center"/>
                        <Label Grid.Column="2" Text="주문상태" TextColor="Black" FontSize="15" VerticalTextAlignment="Center" HorizontalTextAlignment="Center"/>
                        <Label Grid.Column="3" Text="주문가격" TextColor="Black" FontSize="15" VerticalTextAlignment="Center" HorizontalTextAlignment="End"/>
                    </Grid>
                    <BoxView HeightRequest="1" HorizontalOptions="FillAndExpand" Color="Black"/>
                </StackLayout>
            </CollectionView.Header>
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <Grid Margin="0,10,0,0">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="90" />
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="70" />
                            <ColumnDefinition Width="70" />
                        </Grid.ColumnDefinitions>
                        <Label Grid.Column="0" Text="{Binding ORDER_DATE}" TextColor="Black" FontSize="12" VerticalTextAlignment="Center" HorizontalTextAlignment="Center"/>
                        <Label Grid.Column="1" Text="{Binding STORE_NAME}" TextColor="Black" FontSize="13" VerticalTextAlignment="Center" HorizontalTextAlignment="Center"/>
                        <Label Grid.Column="2" Text="{Binding ORDER_STATUS}" TextColor="Black" FontSize="12" VerticalTextAlignment="Center" HorizontalTextAlignment="Center"/>
                        <Label Grid.Column="3" Text="{Binding PRICE, StringFormat='{0:N0}'}" TextColor="#B32026" FontSize="15" VerticalTextAlignment="Center" HorizontalTextAlignment="End"/>
                    </Grid>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>

* EmptyView 는 항목이 없는 경우 중간에 Text 로 표시가 필요할 때 사용한다.

위 내용을 데이터를 체우면 아래 처럼 표시 된다.

 

 

 

애플 개발자 계정에 아이폰 기기를 등록하는 과정을 설명합니다.


1. 앱개발자 사이트 접속 (https://developer.apple.com/account/#/welcome) 하여 Certificates, Identifiers & Profiles 선택


2. 죄측메뉴 중 Devices 메뉴 선택후 우측의 파란바탕의 + 버튼 클릭


3. Device Name 을 입력하고 DeviceID(UDID) 입력

UDID 확인은 iTune 를 연결하여 확인하거나 아래 작성글을 참고해서 폰에서도 확인 가능

(https://kjcoder.tistory.com/985)


4. Register 버튼을 클릭


5. Done 버튼 클릭하여 등록 완료


* 여기 까지만 하면 맥과 폰을 연결해도 비쥬얼 스튜디오에서 목록이 나타나지 않는다.


6. 맥과 폰을 연결하여 iTune 를 실행하여 아래처럼 화면이 뜨면 신뢰 클릭 (폰에서도 신뢰 선택)


7. 비쥬얼 스튜디오에서 기기 목록이 뜨는지 확인


NavigationPage.SetHasNavigationBar(this, false);

NavigationPage  를 쓰면서 메인 페이지에서 백버튼 눌렀을 경우

DisplayAlert (종료확인창)을 띄우는 방법은 아래와 같다.


        protected override bool OnBackButtonPressed() 
        {
            if (Navigation.NavigationStack.LastOrDefault() == null)
            {
                Device.BeginInvokeOnMainThread(new Action(async () =>
                {
                    if (await DisplayAlert("종료확인", "종료하시겠습니까?", "네", "아니오"))
                    {
                        System.Diagnostics.Process.GetCurrentProcess().CloseMainWindow();
                    }
                }));
            }

            return true; 
        }


Navigation.NavigationStack 을 확인하여 메인 페이지 인지 확인한 후 Device.BeginInvokeOnMainThread 를 이용하여 await DisplayAlert 를 이용해 팝업 창을 띄우고 종료한다.

Grid 에서 특정 Row 를 숨기는 방법


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

namespace Foobar.Converters
{

    public class StatusToVisibilityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (Equals(value,null))
                return new GridLength(0);

            var status = value.ToString().ToLower();

            switch (status)
            {
                case ("active"):
                    {
                        return new GridLength(1, GridUnitType.Auto);
                    }
                default:
                    {
                        return new GridLength(0);
                    }
            }
        }
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException("Only one way bindings are supported with this converter");
        }}
    }
}
<Grid AbsoluteLayout.LayoutFlags="All"
      AbsoluteLayout.LayoutBounds="0,1,1,1">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="{Binding Contact.Status, Converter={convert:StatusToVisibilityConverter}}" />
.....


              <ShellContent  Title="test" >
                <ShellContent.ContentTemplate>
                    <DataTemplate>
                        <views:TestPage>
                            <x:Arguments>
                                <x:String>test</x:String>
                            </x:Arguments>
                        </views:TestPage>
                    </DataTemplate>
                </ShellContent.ContentTemplate>


위 내용을 코드로 변환하면 아래와 같습니다.

            ShellContent shellContent = new ShellContent();
            shellContent.Title = "test";
            var template = new DataTemplate(typeof(TestPage)); // 인자 없을때
            var template new DataTemplate(() => { return new TestPage("test"); }); // 인자 있을때
            shellContent.ContentTemplate = data;

ShellContent 를 동적으로 생성하면서 인자를 던지고자 할때 사용하면 유용합니다.^^


<application

    android:usesCleartextTraffic="true">

            ...

</application>```


android 의 AndroidManifest.xml 쪽에 android:usesCleartextTraffic="true" 항목을 추가해주면 된다.


Install-Package Xamarin.AndroidX.Migration -Version 1.0.0-preview06


참고

https://www.nuget.org/packages?q=Tags%3A%22AndroidX%22+Authors%3A%22Microsoft%22

https://devblogs.microsoft.com/xamarin/androidx-for-xamarin/

Picker 에서 UnderLine 제거하는 방법입니다.

BorderlessPicker.cs

namespace SuaveControls.MaterialForms
{
    public class BorderlessPicker : Picker
    {
    }
}

BorderlessPickerRenderer.cs – Android

[assembly: ExportRenderer(typeof(BorderlessPicker), typeof(BorderlessPickerRenderer))]
namespace SuaveControls.MaterialForms.Android.Renderers
{
    public class BorderlessPickerRenderer : PickerRenderer
    {
        public static void Init() { }
        protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
        {
            base.OnElementChanged(e);
            if (e.OldElement == null)
            {
                Control.Background = null;
 
                var layoutParams = new MarginLayoutParams(Control.LayoutParameters);
                layoutParams.SetMargins(0, 0, 0, 0);
                LayoutParameters = layoutParams;
                Control.LayoutParameters = layoutParams;
                Control.SetPadding(0, 0, 0, 0);
                SetPadding(0, 0, 0, 0);
            }
        }
    }
}


BorderlessPickerRenderer.cs – iOS

[assembly: ExportRenderer(typeof(BorderlessPicker), typeof(BorderlessPickerRenderer))]
namespace SuaveControls.MaterialForms.iOS.Renderers
{
    public class BorderlessPickerRenderer : PickerRenderer
    {
        public static void Init() { }
        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
 
            Control.Layer.BorderWidth = 0;
            Control.BorderStyle = UITextBorderStyle.None;
        }
    }

}



BorderlessPickerRenderer.cs – UWP

[assembly: ExportRenderer(typeof(BorderlessPicker), typeof(BorderlessPickerRenderer))]
 
namespace SuaveControls.MaterialForms.UWP.Renderers
{
    public class BorderlessPickerRenderer : PickerRenderer
    {
        public static void Init() { }
        protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
        {
            base.OnElementChanged(e);
 
            if (Control != null)
            {
                Control.BorderThickness = new Windows.UI.Xaml.Thickness(0);
                Control.Margin = new Windows.UI.Xaml.Thickness(0);
                Control.Padding = new Windows.UI.Xaml.Thickness(0);
            }
        }
    }

}


예전에 빌드 했던 앱을 열어서 Nuget 을 모두 업데이트 했는데 

아래 처럼 에러가 발생되었다.



unable to get provider com.google.android.gms.ads.mobileadsinitprovider: java.lang.illegalstateexception


해결방법은 AndroidManifest.xml 파일에

아래처럼 AdMob 에서 할당된 앱의 고유 ID 를 넣으면 해결된다.


<application android:label="UnitConversion" android:icon="@drawable/module48">

    <meta-data

        android:name="com.google.android.gms.ads.APPLICATION_ID"

        android:value="ca-app-pub-4681470946279796~5708961527"/>

</application>


앱의 ID 는 AdMob 사이트에서 아래 처럼 확인 할 수 있다.


이전에는 저 항목이 없어도 광고 표시에 문제가 없었는데 버전업이 되면서 필수 항목으로 바뀐듯하다.



+ Recent posts