Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Directory.build.props
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<LangVersion>latest</LangVersion>
<EnableNETAnalyzers>True</EnableNETAnalyzers>
<AnalysisLevel>latest</AnalysisLevel>
<ReactiveUIVersion>19.*</ReactiveUIVersion>
<ReactiveUIVersion>20.*</ReactiveUIVersion>
</PropertyGroup>
<PropertyGroup>
<SolutionDir Condition="'$(SolutionDir)' == ''">$(MSBuildThisFileDirectory)</SolutionDir>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<RazorLangVersion>3.0</RazorLangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.14" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0" PrivateAssets="all" />
<PackageReference Include="System.Net.Http.Json" Version="7.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.4" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.4" PrivateAssets="all" />
<PackageReference Include="System.Net.Http.Json" Version="8.0.0" />
<PackageReference Include="ReactiveUI.Blazor" Version="$(ReactiveUIVersion)" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
using System;

namespace ClientSideExample.Data
namespace ClientSideExample.Data;

public class WeatherForecast
{
public class WeatherForecast
{
public DateTime Date { get; set; }
public DateTime Date { get; set; }

public int TemperatureC { get; set; }
public int TemperatureC { get; set; }

public string Summary { get; set; }
public string Summary { get; set; }

public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
}
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
19 changes: 9 additions & 10 deletions blazor/ClientSideExample/ClientSideExample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,18 @@
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.DependencyInjection;

namespace ClientSideExample
namespace ClientSideExample;

public static class Program
{
public static class Program
public static async Task Main(string[] args)
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");

builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddSingleton<FetchDataViewModel>();
builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddSingleton<FetchDataViewModel>();

await builder.Build().RunAsync();
}
await builder.Build().RunAsync();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,29 @@
using System.Threading.Tasks;
using ReactiveUI;

namespace ClientSideExample.ViewModels
namespace ClientSideExample.ViewModels;

public class CounterViewModel : ReactiveObject
{
public class CounterViewModel : ReactiveObject
{
private int _currentCount;
private int _currentCount;

private readonly ObservableAsPropertyHelper<int> _count;
private readonly ObservableAsPropertyHelper<int> _count;

public CounterViewModel()
{
public CounterViewModel()
{
Increment = ReactiveCommand.CreateFromTask(IncrementCount);

_count = Increment.ToProperty(this, x => x.CurrentCount, scheduler: RxApp.MainThreadScheduler);
}

public int CurrentCount => _count.Value;
public int CurrentCount => _count.Value;


public ReactiveCommand<Unit, int> Increment { get; }
public ReactiveCommand<Unit, int> Increment { get; }

private Task<int> IncrementCount()
{
private Task<int> IncrementCount()
{
_currentCount++;
return Task.FromResult(_currentCount);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,29 @@
using ReactiveUI;


namespace ClientSideExample.ViewModels
{
public class FetchDataViewModel : ReactiveObject
{
private readonly ObservableAsPropertyHelper<WeatherForecast[]> _forecasts;
namespace ClientSideExample.ViewModels;

private readonly HttpClient _http;
public FetchDataViewModel(HttpClient http)
{
_http = http;
LoadForecasts = ReactiveCommand.CreateFromTask(LoadWeatherForecastsAsync);
public class FetchDataViewModel : ReactiveObject
{
private readonly ObservableAsPropertyHelper<WeatherForecast[]> _forecasts;

_forecasts = LoadForecasts.ToProperty(this, x => x.Forecasts, scheduler: RxApp.MainThreadScheduler);
}
private readonly HttpClient _http;
public FetchDataViewModel(HttpClient http)
{
_http = http;
LoadForecasts = ReactiveCommand.CreateFromTask(LoadWeatherForecastsAsync);

public ReactiveCommand<Unit, WeatherForecast[]> LoadForecasts { get; }
_forecasts = LoadForecasts.ToProperty(this, x => x.Forecasts, scheduler: RxApp.MainThreadScheduler);
}

public WeatherForecast[] Forecasts => _forecasts.Value;
public ReactiveCommand<Unit, WeatherForecast[]> LoadForecasts { get; }

public WeatherForecast[] Forecasts => _forecasts.Value;

private async Task<WeatherForecast[]> LoadWeatherForecastsAsync()
{
return await _http.GetFromJsonAsync<WeatherForecast[]>("sample-data/weather.json");
}

private async Task<WeatherForecast[]> LoadWeatherForecastsAsync()
{
return await _http.GetFromJsonAsync<WeatherForecast[]>("sample-data/weather.json");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,41 @@
using System.Reactive.Linq;
using ReactiveUI;

namespace ClientSideExample.ViewModels
namespace ClientSideExample.ViewModels;

public class GreetingViewModel : ReactiveObject
{
public class GreetingViewModel : ReactiveObject
{
private string _name;
private string _name;

private readonly ObservableAsPropertyHelper<bool> _canClear;
private readonly ObservableAsPropertyHelper<string> _greeting;
private readonly ObservableAsPropertyHelper<bool> _canClear;
private readonly ObservableAsPropertyHelper<string> _greeting;

public ReactiveCommand<Unit, Unit> Clear { get; }
public ReactiveCommand<Unit, Unit> Clear { get; }

public bool CanClear => _canClear.Value;
public bool CanClear => _canClear.Value;

public string Greeting => _greeting.Value;

public string Name
{
get => _name;
set => this.RaiseAndSetIfChanged(ref _name, value);
}

public GreetingViewModel()
{
var canClear = this.WhenAnyValue(x => x.Name)
.Select(name => !string.IsNullOrEmpty(name));

Clear = ReactiveCommand.Create(
() => { Name = string.Empty; },
canClear);

_canClear = Clear.CanExecute
.ToProperty(this, x => x.CanClear);

_greeting = this.WhenAnyValue(x => x.Name)
.Select(x => string.IsNullOrWhiteSpace(x) ? string.Empty : $"Hello, {x}!")
.ToProperty(this, x => x.Greeting);
}
public string Greeting => _greeting.Value;

public string Name
{
get => _name;
set => this.RaiseAndSetIfChanged(ref _name, value);
}

public GreetingViewModel()
{
var canClear = this.WhenAnyValue(x => x.Name)
.Select(name => !string.IsNullOrEmpty(name));

Clear = ReactiveCommand.Create(
() => { Name = string.Empty; },
canClear);

_canClear = Clear.CanExecute
.ToProperty(this, x => x.CanClear);

_greeting = this.WhenAnyValue(x => x.Name)
.Select(x => string.IsNullOrWhiteSpace(x) ? string.Empty : $"Hello, {x}!")
.ToProperty(this, x => x.Greeting);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,17 @@
using System.Threading.Tasks;
using ClientSideExample.ViewModels;

namespace ClientSideExample.Views
namespace ClientSideExample.Views;

public partial class CounterView
{
public partial class CounterView
public CounterView()
{
public CounterView()
{
ViewModel = new CounterViewModel();
}
ViewModel = new CounterViewModel();
}

private async Task IncrementCount()
{
await ViewModel.Increment.Execute().ToTask();
}
private async Task IncrementCount()
{
await ViewModel.Increment.Execute().ToTask();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
using System.Reactive.Threading.Tasks;
using System.Reactive.Linq;
using System.Threading.Tasks;
using ClientSideExample.ViewModels;
using Microsoft.AspNetCore.Components;

namespace ClientSideExample.Views;

namespace ClientSideExample.Views
public partial class FetchDataView
{
public partial class FetchDataView
[Inject]
public FetchDataViewModel FetchViewModel
{
[Inject]
public FetchDataViewModel FetchViewModel
{
get => ViewModel;
set => ViewModel = value;

}
get => ViewModel;
set => ViewModel = value;
}

protected override async Task OnInitializedAsync()
{
await ViewModel.LoadForecasts.Execute().ToTask();
}
protected override async Task OnInitializedAsync()
{
await ViewModel!.LoadForecasts.Execute();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,17 @@
using System.Threading.Tasks;
using ClientSideExample.ViewModels;

namespace ClientSideExample.Views
namespace ClientSideExample.Views;

public partial class GreetingView
{
public partial class GreetingView
public GreetingView()
{
public GreetingView()
{
ViewModel = new GreetingViewModel();
}
ViewModel = new GreetingViewModel();
}

public async Task Clear()
{
await ViewModel.Clear.Execute().ToTask();
}
public async Task Clear()
{
await ViewModel.Clear.Execute().ToTask();
}
}
}