Uno Platform Uno Platform 3.3 - Day 0 support for WinUI 3 Preview 3, Android 11

Uno Platform 3.3이 릴리즈 되었습니다.

 

조만간 정식 릴리즈가될 WinUI 3 Preview를 지원을 추가했습니다. 

 

Uno Platform을 처음 사용하는 사용자를 위해 - WebAssembly를 이용한 Windows, iOS, Android, macOS, Linux 및 웹에서 기본적으로 실행되는 픽셀 단위의 단일 소스 C# 및 XAML 앱을 만들 수 있습니다. Uno Platform은 무료이며 오픈 소스 (Apach 2.0)입니다. Uno Platform을 시작 하기 위해서는 여기를 클릭하세요

 

WinUI 3 Preview 3 support

 

WinUI Desktop 프로젝트 템플릿에 대한 지원을 추가했습니다. 데스크톱 템플릿을 사용하면 WinUI 응용 프로그램이 UWP 샌드 박스에서 실행하지 않고도, .NET 5와 함께 전체 Win32 및 WinRT API를 사용할 수 있습니다.

 

WinUI 3 API를 사용하여 Uno Platform 애플리케이션을 생성하려면 다음 명령을 실행하세요.

dotnet new -i Uno.ProjectTemplates.Dotnet
dotnet new unoapp-winui -o MyApp

dotnet 템플릿에 대한 최신 정보를 여기서 확인 할 수 있습니다.

 

WinUI 3 Preview 지원에 대한 몇 가지 사항

 

. Windows 데스크톱 프로젝트 디버깅 및 실행은 "MyProject.Windows.Desktop" 패키지가 아닌 "MyProject.Windows.Package" 프로젝트를 사용하여 수행해야 합니다.(그렇지 않으면 시작시 오류 발생)

. 템플릿으로 만든 WinUI + UWP 프로젝트는 아직 .NET 5를 지원하지 않지만 C# 8.0 및 .NET Standard 2.0 라이브러리를 지원합니다.

. WinUI 3 Windows 데스크톱 및 UWP 헤드를 실행하려면 Visual Studio 2019 16.9 Preview 1을 설치하는 것이 가장 좋습니다. 다른 프로랫폼의 경우 Visual Studio 2019의 안정적인 최신 빌드를 선택할 수 있습니다.

 

Android 11 and iOS 14 Support

. 현재 Android 11 지원을 제공하고 있으며 11월 1일부터 Google에서 지원ㅇ르 중단 한 Android 9 사용을 중단 합니다.

 

Support for KeyUp and KeyDown Skia backends

키보드는 커뮤니티의 큰 요청이었으며 이 기능의 첫번째 헤택은 Linux용 Uno 계산기입니다. 숫자 및 연산자 입력에 대한 키보드 지원을 사용하도록 Snapped 애플리케이션을 업데이트했습니다.

 

또한 Snap를 지원하지 않는 배포또한 Snap을 지원하지 않는 배포판을 사용 중이거나 Snap이 설치되지 않은 경우 Linux 계산기에 대한 AppImage 지원을 업데이트했습니다.

 

How to Upgrade

Uno Platform의 최신 릴리스로 업그레이드하려면 Visual Studio NuGet 패키지 관리자를 통해 패키지를 3.3으로 업데이트하십시오! Uno Platform을 처음 사용하는 경우 시작하는 가장 좋은 방법은 공식 시작 안내서를 따르는 것입니다.

 

Webinar: Uno Platform and .NET 5 (Dec 17th, 2020, Noon EST)

Uno Platform에서 .NET 5에 대한 지원을 추가하면 성능을 향상시키고 솔루션 복잡성을 줄일 수있는 여러 기회가 생성됩니다. .NET 5를 사용하면 기존 Microsoft Windows 대상뿐 아니라 WebAssembly, Linux, macOS, iOS 및 Android도 대상으로 더 잘 지정할 수 있습니다. Uno Platform이 .NET 5 및 WinUI를 활용하는 방법에 대한 30 분 개요와 CTO Jerome Laban과의 실시간 Q & A에 참여하십시오.

블로그 이미지

kaki104

This blog covers the latest technologies in Microsoft .Net. In 2020, I will be talking about Uno Platform frequently. http://youtube.com/FutureOfDotNet https://twitter.com/kaki104

댓글을 달아 주세요

2020년은 오프라인 비지니스 환경에서 언텍트 비지니스 환경으로 변화하는 변곡점이라고 있을 같습니다. 그에 따라 이제는 PC 뿐만 아니라 다양한 모바일 디바이스에서 실행되는 크로스플랫폼 개발 환경이 더욱더 발전을 것이라고 생각됩니다.

 

2018 5 최초로 공개된 Uno Platform 크로스 플랫폼에서 실행되는 비지니스 응용 프로그램을 개발하는 가장  빠른 방법이라고 생각하며, 포스트에서 Microsoft Contoso UWP앱을 Uno Platform Prism으로 포팅할 참고할 사항이나 필요한 기술에 대해서 이야기를 하려고 합니다. Uno Platform 대한 자세한 사항은 여기 참고하시기 바랍니다.

 

Contoso UWP app

https://github.com/microsoft/Windows-appsample-customers-orders-database

UnoContoso app – Uno Platform

Uno.Samples/UI/UnoContoso at master · unoplatform/Uno.Samples (github.com)

 

포팅시 어려웠던 부분?

  1. Entity Framework Core 버전이 2.1에서 3.x 버전으로 변경되면서 발생한 문제를 해결하는데  시간이 오래 걸렸습니다. 변경 사항은 여기 참고하시기 바랍니다.
  2. Sqlite Entity Framework Core 이용해서 앱에서 직접 접근해서 사용하는 방식이 Wasm, iOS, macOS 등에서 원활하지 않아서, Web API 통해서만 사용할 있도록 수정하는데 시간이 걸렸습니다.
  3. Contoso UWP앱이 Event-driven 방식을 사용하고 있어서, 부분을 MVVM Pattern으로 변경하는 부분도 시간이 걸렸습니다.

프로젝트에 대한 간단한 설명

  • UnoContoso.Droid : 안드로이드 해더 프로젝트
  • UnoContoso.iOS : iOS 헤더 프로젝트
  • UnoContoso.macOS : macOS 헤더 프로젝트
  • UnoContoso.Uwp : Uwp 헤더 프로젝트
  • UnoContoso.Wasm : Wasm 헤더 프로젝트
  • UnoContoso.Models : 모델 프로젝트, .NET Standard 2.0
  • UnoContoso.Repository : 레파지토리 프로젝트, .NET Standard 2.0
  • UnoContoso.Service : 서비스 프로젝트, .NET Core 3.1
  • UnoContoso.Shared : 공유 프로젝트

Tips

  • NavigationView
    • AlwaysShowHeader=”False” :상단에 헤더를 표시하지 않습니다. 헤더를 표시하는 보다 표시 하지 않는 것이 아래의 이유로 인해서 개발이 용이 합니다.
      • iOS 경우 헤더의 위치가 다른 플랫폼과 다르게 위로 올라가서 표시됩니다.
      • Windows, Wasm, macOS에서는 헤더 위치에 CommandBar 표시하고, Android, iOS에서는 화면 하단에 표시하기 때문에, NavigationView.HeaderTemplate 사용이 어렵습니다.
    • NavigationViewBehavior : NavigationView 표시되는 메뉴를 동적으로 구현하고, 선택된 Menu ViewModel 바인딩하기 위해서 Behavior 만들었습니다. Behavior 일반적인 사항은 여기 참고하시기 바랍니다.
    • ContentControl : Prism에서 일반적으로 Region 지정하는 컨트롤입니다. 컨트롤을 통해서 View 네비게이션 됩니다. 자세한 사항은 Prism RegionNavigation 참고하시기 바랍니다.
      • 컨트롤의 Padding 화면의 기본 Margin입니다.
      • iOS 경우 ios:Padding=”10,20,0,0” 사용해야 합니다.
<!--Code1-->
        <NavigationView
            IsBackButtonVisible="Collapsed"
            OpenPaneLength="160"
            IsSettingsVisible="False"
            AlwaysShowHeader="False"
            IsTabStop="False">
            <i:Interaction.Behaviors>
                <behaviors:NavigationViewBehavior 
                    MenuItems="{Binding Menus}"
                    SelectedMenuItem="{Binding SelectedItem, Mode=TwoWay}"/>
            </i:Interaction.Behaviors>
            <ContentControl 
                prismRegions:RegionManager.RegionName="ContentRegion" 
				HorizontalContentAlignment="Stretch"
				VerticalContentAlignment="Stretch"
                not_ios:Padding="10,0,0,0"
                ios:Padding="10,20,0,0"/>
        </NavigationView>
  • x:Bind
    • Android iOS 앱의 성능 향상을 위해서 x:Bind 주로 사용했습니다.
    • x:Bind 사용하기 위해서 code behind에서ViewModel이라는 프로퍼티를 추가합니다. (Code2-1)
    • x:Bind 기본 mode OneTime입니다. 그래서, 프로퍼티의 데이터가 변경되는 곳이라면 mode=OneWay 반드시 추가해야 합니다.
    • 컨트롤의 이벤트와 뷰모델의 메소드를 x:Bind 직접 연결하는 방법은 사용할 없습니다.
    • IValueConverter 이용하는 경우 Android에서  x:Bind 사용할 없기 때문에, Binding 사용합니다. (Code2-2)
//Code2-1
public CustomerListViewModel ViewModel
{
    get { return DataContext as CustomerListViewModel; }
}
<!--Code2-2-->
                <TextBlock
                    Grid.Column="0"
                    Margin="0" Padding="0"
                    Text="{x:Bind Product.Name}" />
                <TextBlock
                    Grid.Column="2"
                    Margin="0" Padding="0"
                    HorizontalAlignment="Right"
                    Text="{Binding Product.ListPrice,
                        Converter={StaticResource StringFormatConverter},
                        ConverterParameter='{}{0:n}'}" />
  • Prism
    • View ViewModel 자동으로 연결해 줍니다. prismMvvm:ViewModelLocator.AutowireViewModel="True" 코드를 참고 합니다. 자세한 사항은 여기를 참고 합니다.(Code3-1)
    • RegionNavigation 사용하기 위해서는 App.xaml.cs → void RegisterTypes() 메소드에 RegisterForNavigation 이용해서 등록해야 합니다. (Code3-2)
    • DialogService 사용하는 화면은 View ViewModel 수동으로 연결 합니다. App.xaml.cs -} void RegisterTypes() 메소드에 있는 코드를 참고 합니다.   자세한 사항은 여기 참고 합니다. (Code3-3)
    • DelegateCommand ObservesProperty 이용하면, Command 사용여부를 쉽게 변경할 있습니다. 자세한 사항은 여기 참고 합니다. (Code3-4)
    • EventAggregator 이용하면 뷰모델과 뷰모델 사이에 커뮤니케이션을 있습니다. 이는 Loosely Coupled 연결입니다. 자세한 사항은 여기 참고 합니다. (Code3-5)
<!--Code3-1-->
<UserControl
    x:Class="UnoContoso.Views.OrderDetailView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:UnoContoso.Views"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:i="using:Microsoft.Xaml.Interactivity" 
    xmlns:ic="using:Microsoft.Xaml.Interactions.Core"
    xmlns:toolkit="using:Microsoft.Toolkit.Uwp.UI.Controls"
    xmlns:prismMvvm="using:Prism.Mvvm" 
    prismMvvm:ViewModelLocator.AutowireViewModel="True"
    xmlns:uc="using:UnoContoso.UserControls" 
    xmlns:stateTriggers="using:UnoContoso.StateTriggers" 
    xmlns:models="using:UnoContoso.Models" 
    x:Name="Root"
    mc:Ignorable="d">
//Code3-2
containerRegistry.RegisterForNavigation<CustomerListView>();
containerRegistry.RegisterForNavigation<CustomerDetailView>();
containerRegistry.RegisterForNavigation<HomeView>();
containerRegistry.RegisterForNavigation<OrderListView>();
containerRegistry.RegisterForNavigation<OrderDetailView>();
//Code3-3
containerRegistry.RegisterDialog<MessageControl, MessageViewModel>();
containerRegistry.RegisterDialog<ConfirmControl, ConfirmViewModel>();
//Code3-4
            ViewDetailCommand = new DelegateCommand(OnViewDetail,
                () => SelectedCustomer != null)
                .ObservesProperty(() => SelectedCustomer);
//Code3-5
Step 1. CustomerListViewModel.cs
            EventAggregator.GetEvent<CustomerEvent>()
                .Subscribe(ReceivedCustomerEvnet, false);

Step 2. CustomerDetailViewModel.cs
            EventAggregator.GetEvent<CustomerEvent>()
                .Publish(new EventArgs.CustomerEventArgs 
                { 
                    Changes = change,
                    Customer = Customer.Model
                });
                
Step 3. CustomerListViewModel.cs
        private void ReceivedCustomerEvnet(CustomerEventArgs obj)
        {
            switch (obj.Changes)
            {
                case Enums.EntityChanges.None:
                    break;
                case Enums.EntityChanges.Changed:
                    {
                        var customer = _allCustomers
                            .FirstOrDefault(c => c.Model.Id == obj.Customer.Id);
                        if (customer == null) return;
                        customer.Model = obj.Customer;
                        customer.UpdateProperty();
                    }
                    break;
                case Enums.EntityChanges.Added:
                    {
                        var customer = new CustomerWrapper(_contosoRepository, obj.Customer);
                        _allCustomers.Add(customer);
                    }
                    break;
                case Enums.EntityChanges.Deleted:
                    {
                        var customer = _allCustomers
                            .FirstOrDefault(c => c.Model.Id == obj.Customer.Id);
                        if (customer == null) return;
                        _allCustomers.Remove(customer);
                    }
                    break;
            }
        }
  • RelativePanel
    • 컨트롤을 관계에 의해 배치 합니다. 자세한 사항은 여기 참고 하시기 바랍니다.
    • VisualState 이용해서 상단에 위치한 CommandBar 위치를 하단으로 변경할 CommandBar 컨트롤에 RelativePanel.LeftOf RelativePanel.RightOf 입력되어있는 이름을 지워주어야 하단으로 이동이 가능합니다. 부분은 UWP에서의 동작과는 다르게 동작합니다.
<!--Code4-->
<VisualState>
  <VisualState.StateTriggers>
    <stateTriggers:MobileScreenTrigger />
  </VisualState.StateTriggers>
  <VisualState.Setters>
    <Setter Target="mainCommandBar.(RelativePanel.AlignBottomWithPanel)" Value="True" />
    <Setter Target="mainCommandBar.(RelativePanel.AlignLeftWithPanel)" Value="True" />
    <Setter Target="mainCommandBar.(RelativePanel.AlignRightWithPanel)" Value="True" />
    <Setter Target="mainCommandBar.(RelativePanel.LeftOf)" Value="" />
    <Setter Target="mainCommandBar.(RelativePanel.RightOf)" Value="" />
    <Setter Target="mainCommandBar.HorizontalAlignment" Value="Stretch" />
    <Setter Target="PageTitle.Margin" Value="30,4,0,0"/>
    <Setter Target="CustomerSearchBox.Width" Value="240" />
    <Setter Target="RootDataGrid.Margin" Value="0,10,0,40" />
    <Setter Target="CustomerListMobileView.Visibility" Value="Visible"/>
    <Setter Target="CustomerDataGrid.Visibility" Value="Collapsed"/>
  </VisualState.Setters>
</VisualState>
  • CommandBar
    • 커맨드 버튼을 배치하는 컨트롤 입니다. 기본적인 사항은 여기 참고하시기 바랍니다.
    • CommandBarBehavior 크기가 변하면 DefaultLabelPosition Right에서 Bottom으로 이동 시키기 위해서 추가한 Behavior입니다.
    • DefaultLabelPosition 프로퍼티가 Uno에서 미구현 프로퍼티이기 때문에, 대부분의 플랫폼에서는 기본값 Bottm 가지고 있습니다.
<!--Code5-->
            <CommandBar 
                x:Name="mainCommandBar"
                Background="White"
                HorizontalAlignment="Right"
                DefaultLabelPosition="Right"
                RelativePanel.LeftOf="CustomerSearchBox"
                RelativePanel.RightOf="PageTitle">
                <i:Interaction.Behaviors>
                    <behaviors:CommandBarBehavior/>
                </i:Interaction.Behaviors>
                <AppBarButton
                    Icon="Contact"
                    Label="View details"
                    ToolTipService.ToolTip="View details" 
                    Command="{x:Bind ViewModel.ViewDetailCommand}"/>
                <!--skip lines-->
                <AppBarButton
                    Icon="Refresh"
                    Label="Sync"
                    ToolTipService.ToolTip="Sync with server" 
                    Command="{x:Bind ViewModel.SyncCommand}"/>
            </CommandBar>
  • CollapsibleSearchBox
    • UserControl 이용해서 만든 검색용 컨트롤입니다.
    • Uno에서 그래픽 아이콘은 SymbolIcon 컨트롤을 이용해야, 플랫폼에서도 정상적으로 아이콘이 출력됩니다.
<!--Code6-->
        <ToggleButton
            x:Name="searchButton"
            HorizontalAlignment="Right"
            VerticalAlignment="Top"
            Background="Transparent"
            Checked="SearchButton_Checked"
            Visibility="Collapsed"
            Padding="4">
            <SymbolIcon Symbol="Find" />
        </ToggleButton>
  • ListView
    • 모바일 디바이스에서는 화면에 출력되는 항목의 갯수와 가로 스크롤바의 유무에 따라서 세로 스크롤 성능에 영향을 미치기 때문에 DataGrid보다는 ListView 이용하는 것이 좋습니다. 자세한 사항은 여기 참고 합니다.
    • macOS에서는 아직 DataGrid 사용할 없기 때문에 ListView 사용합니다. 하지만, macOS ListView 컨트롤 내부에 ScrollView 없기 때문에 세로 스크롤이 불가능한 것으로 보입니다. macOS 지원은 점점 추가될 것으로 생각합니다.
  • DataGrid
    • Data Grid 형태로 보여주며, 수정도 가능한 컨트롤이며, Windows Community Toolkit 설치해야 사용할 있습니다. 자세한 사항은 여기 참고 합니다.
    • DataGridBehavior Sort기능과 마우스 오른쪽 버튼을 지원하기 위해서 만들었습니다.
    • 컬럼에 프로퍼티를 바인딩 할때 x:Bind 사용할 없습니다.
<!--Code7-->
<toolkit:DataGrid
    x:Name="OrderListDataGrid" BorderThickness="0" 
    CanUserReorderColumns="False" CanUserResizeColumns="False"
    GridLinesVisibility="None" IsReadOnly="True"
    AutoGenerateColumns="False" Margin="0,10,0,0"
    ItemsSource="{x:Bind ViewModel.Orders, Mode=OneWay}"
    SelectedItem="{x:Bind ViewModel.SelectedOrder, Mode=TwoWay}"
    ContextFlyout="{StaticResource DataGridContextMenu}">
	<i:Interaction.Behaviors>
	  <behaviors:DataGridBehavior/>
	</i:Interaction.Behaviors>
	<toolkit:DataGrid.Columns>
	  <toolkit:DataGridTextColumn
	    Header="Invoice" Tag="InvoiceNumber" Binding="{Binding InvoiceNumber}"/>
	  <toolkit:DataGridTextColumn
	    Header="Customer" Tag="CustomerName" Binding="{Binding CustomerName}"/>
	  <toolkit:DataGridTemplateColumn
	    Header="Date" Tag="DatePlaced">
	    <toolkit:DataGridTemplateColumn.CellTemplate>
	      <DataTemplate>
	        <TextBlock
	          VerticalAlignment="Center" Margin="12,0"
		   Text="{Binding DatePlaced, Mode=OneWay,
                     Converter={StaticResource StringFormatConverter},
                     ConverterParameter='{}{0:d}'}" />
	      </DataTemplate>
	    </toolkit:DataGridTemplateColumn.CellTemplate>
	  </toolkit:DataGridTemplateColumn>
         <!-- Skip lines -->
	  <toolkit:DataGridTextColumn
	    Header="Status" Binding="{Binding Status}"/>
	</toolkit:DataGrid.Columns>
</toolkit:DataGrid>
  • VisualState
    • 특정 상태일 UI 요소의 시각적 모양을 지정할 있는 기능입니다. 자세한 사항은 여기 참고 합니다.
    • AdaptiveTrigger : 윈도우 속성을 기반으로 시각적 상태를 선언하는 트리거 입니다. 자세한 사항은 여기 참고 합니다.  
    • VisualState 이용해서 디자인 작업을 할 , 기본 크기에 대한 디자인은 화면에 왼쪽 상단에서8” Tablet(1280x800) 선택하고, 최소 크기에 대한 디자인은 6”Phone(1920x1080) 선택해서 작업하면 약간 편하게 작업할 있습니다.
    • 최소 크기인 경우 PageTitle 컨트롤의 왼쪽에 30 Margin 추가해서 햄버거 버튼과 겹치는 현상을 방지 합니다.
    • MobileScreenTrigger 윈도우 크기가 변경될 실행 중인 디바이스의 이름을 가지고 오고, Mobile이라는 이름을 포함하면 SetActive() 이용해서 VisualState 변경합니다. UIViewSettings.GetForCurrentView().UserInteractionMode Uno에서  미구현 상태라 주석 처리를 했습니다.
<!--Code8-->
<VisualStateManager.VisualStateGroups>
  <VisualStateGroup>
    <VisualState>
      <VisualState.StateTriggers>
        <AdaptiveTrigger MinWindowWidth="{StaticResource LargeWindowSnapPoint}" />
      </VisualState.StateTriggers>
    </VisualState>
  <VisualState>
    <VisualState.StateTriggers>
      <AdaptiveTrigger MinWindowWidth="{StaticResource MediumWindowSnapPoint}" />
    </VisualState.StateTriggers>
  </VisualState>
  <VisualState>
    <VisualState.StateTriggers>
      <AdaptiveTrigger MinWindowWidth="{StaticResource MinWindowSnapPoint}" />
    </VisualState.StateTriggers>
    <VisualState.Setters>
      <Setter Target="PageTitle.Margin" Value="30,4,0,0"/>
    </VisualState.Setters>
  </VisualState>
  <VisualState>
    <VisualState.StateTriggers>
      <stateTriggers:MobileScreenTrigger />
    </VisualState.StateTriggers>
    <VisualState.Setters>
    <!-- Skip lines -->
    </VisualState.Setters>
  </VisualState>
  </VisualStateGroup>
</VisualStateManager.VisualStateGroups>
  • BackButton
    • 뒤로가기 버튼입니다. GoBackCommand 커맨드는 ViewModelBase 선언되어 있습니다.
<!--Code9-->
            <Button 
                x:Name="BackButton"
                Style="{StaticResource NavigationBackButtonNormalStyle}"
                Command="{x:Bind ViewModel.GoBackCommand}"/>
  • TextBox
    • 일반 텍스트를 표시하고 편집하는 사용하는 컨트롤 입니다. 자세한 사항은 여기 참고 합니다.
    • Text 프로퍼티에 TwoWay바인딩을 때는 UpdateSourceTrigger=PropertyChanged 이용하는 것이 좋습니다. 왜냐하면, 내용을 수정하면 바로 바인딩된 프로퍼티가 수정되기 때문입니다. 기본값은 LostFocus입니다. 
<!--Code10-->
<TextBox
    x:Name="FirstName"
    MinWidth="120"
    Margin="0,8,16,8"
    Header="First name"
    IsReadOnly="{x:Bind ViewModel.Customer.IsInEdit, 
	    Converter={StaticResource BoolNegationConverter}, Mode=OneWay}"
    RelativePanel.AlignLeftWithPanel="True"
    Text="{x:Bind ViewModel.Customer.FirstName, Mode=TwoWay, 
	    UpdateSourceTrigger=PropertyChanged}" />
  • InvoiceTemplate (DataTemplate)
    • 데이터 개체의 시각적 구조를 만드는데 사용합니다. 자세한 사항은 여기 참고 합니다.
    • HyperlinkButton 1개가 존재하며 Command win not_win으로 나누어져 있습니다. 각 플랫폼별 xaml 코드를 적용하는 방법은 여기를 참고 합니다.
    • Windows에서는 win:Command="{Binding Source={StaticResource ViewModelElement}, Path=ViewModel.ViewInvoiceCommand}" 사용해야 Command 실행됩니다.
    • Windows 아닌 경우에는 not_win:Command="{Binding ElementName=DataGrid,                     Path=DataContext.ViewInvoiceCommand}" 사용해야 Command 실행됩니다.
    • Windows에서 ElementName=DataGrid 이용하는 방법이 않되는 이유는 모릅니다.
<!--Code11-->
<DataTemplate x:Key="InvoiceTemplate">
    <HyperlinkButton
        Content="{Binding InvoiceNumber}"
        Margin="12,0"
        win:Command="{Binding Source={StaticResource ViewModelElement}, 
            Path=ViewModel.ViewInvoiceCommand}"
        not_win:Command="{Binding ElementName=DataGrid, 
            Path=DataContext.ViewInvoiceCommand}"
        CommandParameter="{Binding}"/>
</DataTemplate>
  • Etc
    • 만약 솔루션에 .Net Standard 프로젝트를 포함하고, 사용한다면, Wasm 프로젝트의 LinkerConfig.xml 파일에 해당 내용을 추가해야 합니다.
<!—LinkerConfig.xml -->
<linker>
  <assembly fullname="UnoContoso.Wasm" />
  <assembly fullname="Uno.UI" />
  <assembly fullname="System.Core">
	<!-- This is required by JSon.NET and any expression.Compile caller -->
	<type fullname="System.Linq.Expressions*" />
  </assembly>
  <assembly fullname="UnoContoso.Models"/>
  <assembly fullname="UnoContoso.Repository"/>
</linker>

이상으로 작업을 하면서 알게된 몇가지 팁들을 정리했습니다. 앞으로도 좋은 정보가 있으면 꾸준히 올리도록 하겠습니다.

Facebook : https://www.facebook.com/kaki104

Twitter : https://twitter.com/kaki104

Youtube : http://youtube.com/FutureOfDotNet

 

블로그 이미지

kaki104

This blog covers the latest technologies in Microsoft .Net. In 2020, I will be talking about Uno Platform frequently. http://youtube.com/FutureOfDotNet https://twitter.com/kaki104

댓글을 달아 주세요

마이크로소프트의 Contoso UWP앱을 UnoContoso 앱으로 포팅한 결과를 다루는 것으로, Uno Platform으로 비지니스 앱을 만들 수 있는지 여러분들이 판단해 보시기 바랍니다.

 

My troubles

  • Does the UI output the same for each platform?
  • I haven't made any Android or iOS apps before. Is it okay?
  • Can it run on Windows 7?
  • It's nice if it runs on macOS too...(Even a simple screen...)
  • Are there cross-platforms running on IoT devices?
  • Will there be enough performance to use for each platform without any problems?

Contoso UWP app

UnoContoso app

 

 

Difficulties in porting

Can I make business apps with the Uno Platform.pdf
1.14MB

youtu.be/ANPVsLc5Hoo

 

블로그 이미지

kaki104

This blog covers the latest technologies in Microsoft .Net. In 2020, I will be talking about Uno Platform frequently. http://youtube.com/FutureOfDotNet https://twitter.com/kaki104

댓글을 달아 주세요

Simple RSS Reader creation is complete.

블로그 이미지

kaki104

This blog covers the latest technologies in Microsoft .Net. In 2020, I will be talking about Uno Platform frequently. http://youtube.com/FutureOfDotNet https://twitter.com/kaki104

댓글을 달아 주세요