Skip to content

Commit

Permalink
Merge pull request #1997 from unoplatform/feature/csharpmarkup
Browse files Browse the repository at this point in the history
  • Loading branch information
agneszitte authored Nov 1, 2023
2 parents 17ce980 + afe8576 commit 3115cb9
Show file tree
Hide file tree
Showing 34 changed files with 5,824 additions and 0 deletions.
487 changes: 487 additions & 0 deletions doc/Learn/Tutorials/Markup/HowTo-CreateMarkupProject.md

Large diffs are not rendered by default.

220 changes: 220 additions & 0 deletions doc/Learn/Tutorials/Markup/HowTo-CustomMarkupProject-MVUX.md
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)
Loading

0 comments on commit 3115cb9

Please sign in to comment.