-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1997 from unoplatform/feature/csharpmarkup
- Loading branch information
Showing
34 changed files
with
5,824 additions
and
0 deletions.
There are no files selected for viewing
487 changes: 487 additions & 0 deletions
487
doc/Learn/Tutorials/Markup/HowTo-CreateMarkupProject.md
Large diffs are not rendered by default.
Oops, something went wrong.
220 changes: 220 additions & 0 deletions
220
doc/Learn/Tutorials/Markup/HowTo-CustomMarkupProject-MVUX.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,220 @@ | ||
--- | ||
uid: Learn.Tutorials.HowToCustomMarkupProjectMVUX | ||
--- | ||
|
||
# How to set up your own C# Markup project using MVUX | ||
|
||
You can use this tutorial to learn how to set up a Uno Platform project using MVUX. | ||
|
||
Create a new project using MVUX | ||
|
||
- In this tutorial, you will [set up the environment and create the Markup project and MVUX](xref:Learn.Tutorials.HowToMarkupMVUX) | ||
|
||
## Start With MVUX. | ||
|
||
The MVUX provides a structured approach to managing the application state and updating the user interface within the Uno Platform, following the principles of MVU architecture. | ||
It aims to simplify state management and UI development by providing abstractions and conventions for working with feeds, states, and views. | ||
|
||
In this tutorial, you can learn about the [MVUX](xref:Overview.Mvux.Overview) using XAML. | ||
|
||
The same concept can be applied to C# Markup. | ||
|
||
By the way, let's use the same existing example in XAML to make the conversation in C# Markup. | ||
Let's try to simplify the use to be able to explain the features. | ||
|
||
**WeatherApp Sample XAML** | ||
|
||
You can find the code for our weather app here: https://github.com/unoplatform/Uno.Samples/tree/master/UI/MvuxHowTos/WeatherApp | ||
|
||
|
||
|
||
### Add elements and set attributes on the UI. | ||
|
||
Change the *MainPage* to have a different content as the sample bellow. | ||
|
||
- Customizing the UI | ||
|
||
# [**C# Markup**](#tab/cs) | ||
|
||
#### C# Markup. | ||
|
||
- The code below shows how to use the FeedView to list information on MVUX. | ||
But first to have the information we will create the WeatherModel and the WeatherService. | ||
|
||
First, let's create the Weather Service. | ||
Create a class file named `WeatherService.cs` and add the content below to the file. | ||
In this File we will create a record WeatherInfo with contains the attribute Temperature. | ||
After that, we create an IWeatherService, (With defining the GetCurrentWeather) and an implementation of it on the WeatherService. | ||
For this case, just have a new WeatherInfo with a random temperature. | ||
|
||
> Notice that the WeatherInfo is been created for every new request, following the MVU standard. | ||
```csharp | ||
namespace MySampleProjectMVUX; | ||
|
||
public partial record WeatherInfo(int Temperature); | ||
|
||
public interface IWeatherService | ||
{ | ||
ValueTask<WeatherInfo> GetCurrentWeather(CancellationToken ct); | ||
} | ||
|
||
public class WeatherService : IWeatherService | ||
{ | ||
public async ValueTask<WeatherInfo> GetCurrentWeather(CancellationToken ct) | ||
{ | ||
await Task.Delay(TimeSpan.FromSeconds(1), ct); | ||
return new WeatherInfo(new Random().Next(-40, 40)); | ||
} | ||
} | ||
``` | ||
|
||
Next, let's create the Model. | ||
Create a class file named `WeatherModel.cs` and add the content below to the file. | ||
In this case, we are creating a `WeatherModel` which contains an `IFeed` of the `WeatherInfo`. | ||
|
||
```csharp | ||
namespace MySampleProjectMVUX; | ||
|
||
using Uno.Extensions.Reactive; | ||
|
||
public partial record WeatherModel(IWeatherService WeatherService) | ||
{ | ||
public IFeed<WeatherInfo> CurrentWeather => Feed.Async(WeatherService.GetCurrentWeather); | ||
} | ||
``` | ||
|
||
And now we need to add the DataContext to the Page. | ||
|
||
> Notice that we are using the class BindableWeatherModel auto generated by the MVUX. | ||
|
||
```csharp | ||
this.DataContext = new BindableWeatherModel(new WeatherService()); | ||
|
||
this.DataContext<BindableWeatherModel>((page, vm) => page | ||
); | ||
|
||
``` | ||
|
||
And after that add the FeedView. | ||
|
||
|
||
```csharp | ||
new FeedView() | ||
.Source(() => vm.CurrentWeather) | ||
//.Source(x => x.Bind(() => vm.CurrentWeather)) | ||
//You can use the Function | ||
.DataTemplate((sample) => GetDataTemplate()) | ||
|
||
//Or you can use direct the Element | ||
.ProgressTemplate<StackPanel>((sample) => | ||
new StackPanel().Children( | ||
new TextBlock().Text("Loading...") | ||
) | ||
) | ||
``` | ||
|
||
# [**XAML**](#tab/cli) | ||
|
||
#### XAML | ||
|
||
MainPage.xaml | ||
|
||
```xml | ||
<mvux:FeedView Source="{Binding CurrentWeather}"> | ||
<DataTemplate> | ||
<StackPanel> | ||
<TextBlock DataContext="{Binding Data}" Text="{Binding Temperature}" /> | ||
<Button Content="Refresh" Command="{Binding Refresh}" /> | ||
</StackPanel> | ||
</DataTemplate> | ||
<mvux:FeedView.ProgressTemplate> | ||
<DataTemplate> | ||
<TextBlock Text="Requesting temperature..."/> | ||
</DataTemplate> | ||
</mvux:FeedView.ProgressTemplate> | ||
</mvux:FeedView> | ||
``` | ||
|
||
MainPage.xaml.cs | ||
|
||
```csharp | ||
public MainPage() | ||
{ | ||
this.InitializeComponent(); | ||
|
||
this.DataContext = new BindableWeatherModel(new WeatherService()); | ||
} | ||
``` | ||
# [**Full Code**](#tab/code) | ||
|
||
#### Full C# Markup code | ||
|
||
- Example of the complete code on the MainPage.cs, so you can follow along in your own project. | ||
|
||
```csharp | ||
namespace MySampleProjectMVUX; | ||
using Uno.Extensions.Reactive.UI; | ||
|
||
public sealed partial class MainPage : Page | ||
{ | ||
public MainPage() | ||
{ | ||
|
||
this.DataContext = new BindableWeatherModel(new WeatherService()); | ||
|
||
this.DataContext<BindableWeatherModel>((page, vm) => page | ||
.Background(ThemeResource.Get<Brush>("ApplicationPageBackgroundThemeBrush")) | ||
.Content( | ||
new StackPanel() | ||
.VerticalAlignment(VerticalAlignment.Center) | ||
.HorizontalAlignment(HorizontalAlignment.Center) | ||
.Children( | ||
new TextBlock() | ||
.Text("Hello Uno Platform!"), | ||
new FeedView() | ||
.Source(() => vm.CurrentWeather) | ||
.Source(x => x.Bind(() => vm.CurrentWeather)) | ||
|
||
//You can use the Function | ||
.DataTemplate((sample) => GetDataTemplate()) | ||
|
||
//Or you can use direct the Element | ||
.ProgressTemplate<StackPanel>((sample) => | ||
new StackPanel().Children( | ||
new TextBlock().Text("Loading...") | ||
) | ||
) | ||
) | ||
) | ||
); | ||
} | ||
//Using Template | ||
public StackPanel GetDataTemplate() | ||
{ | ||
return new StackPanel() | ||
.Orientation(Orientation.Vertical) | ||
.Children( | ||
new TextBlock() | ||
.Margin(10) | ||
//.DataContext(x => x.Bind("Data")) | ||
//.Text(x => x.Bind("Temperature")) | ||
.Text("Temperature") | ||
//, | ||
//new Button() | ||
// .Margin(10) | ||
// .Content("Refresh") | ||
// .Command(x => x.Bind("Refresh")) | ||
); | ||
} | ||
} | ||
|
||
``` | ||
|
||
## Next Steps | ||
|
||
- [Custom your own C# Markup - Learn how to change Visual States and User Controls](xref:Learn.Tutorials.HowToCustomMarkupProjectVisualStates) | ||
- [Custom your own C# Markup - Learn how to use Toolkit](xref:Learn.Tutorials.HowToCustomMarkupProjectToolkit) | ||
- [Custom your own C# Markup - Learn how to Change the Theme](xref:Learn.Tutorials.HowToCustomMarkupProjectTheme) | ||
- [Custom your own C# Markup - Learn how to use MVUX](xref:Learn.Tutorials.HowToCustomMarkupProjectMVUX) |
Oops, something went wrong.