当前位置: 首页 > news >正文

Avalonia:基础导航

Avalonia本身就可以实现导航功能,在主页面放置 TransitioningContentControl 控件,把它绑定到ViewModel 中的一个属性上 ViewModelBase? _currentPage;,通过更新这个属性实现导航。
我们先建二个ViewModel,一个是ColorsViewModel,一个是AboutViewModel。

using Avalonia.Data.Converters;
using Avalonia.Media;
using ReactiveUI.SourceGenerators;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;namespace BasicRoutingExample.ViewModels
{public partial class ColorsViewModel : ViewModelBase{[Reactive]private string? _colorName;[Reactive]private Color? _color;public static FuncValueConverter<Color, string> ToCMYK { get; } = new(color =>{double r = color.R / 255.0;double g = color.G / 255.0;double b = color.B / 255.0;double k = 1 - Math.Max(Math.Max(r, g), b);double C = k < 1 ? (1 - r - k) / (1 - k) : 0;double M = k < 1 ? (1 - g - k) / (1 - k) : 0;double Y = k < 1 ? (1 - b - k) / (1 - k) : 0;return $"C={Math.Round(C * 100, 1)}% M={Math.Round(M * 100, 1)}% Y={Math.Round(Y * 100, 1)}% K={Math.Round(k * 100, 1)}%";});public ObservableCollection<ColorsViewModel> Colors { get; } = [];public ColorsViewModel() { }[ReactiveCommand]private void Init(){var properties = typeof(Colors).GetProperties(BindingFlags.Static | BindingFlags.Public).Where(p => p.PropertyType == typeof(Color));foreach (var property in properties){if (property.GetValue(null) is Color color){Colors.Add(new ColorsViewModel{Color = color,ColorName = property.Name});}}}}
}
using System.Reflection;namespace BasicRoutingExample.ViewModels
{public partial class AboutViewModel : ViewModelBase{public string? AppName => Assembly.GetExecutingAssembly().GetName().Name;public string? Version => Assembly.GetExecutingAssembly().GetName()?.Version?.ToString();public string Message => "这是用 Avalonia 设计的 App,使用 ReactiveUI 响应式框架。";}
}

再建二个View。先建ColorsView。

<UserControl xmlns="https://github.com/avaloniaui"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:vm="using:BasicRoutingExample.ViewModels"xmlns:b="using:BasicRoutingExample.Behaviors"xmlns:cv="using:Avalonia.Controls.Converters"mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="560"			 x:DataType="vm:ColorsViewModel"b:LoadedBehavior.ExecuteCommandOnLoaded="{Binding InitCommand}"x:Class="BasicRoutingExample.Views.ColorsView"><UserControl.Resources><cv:ColorToHexConverter x:Key="ColorToHex" AlphaPosition="Leading" IsAlphaVisible="False"/>			</UserControl.Resources><Grid RowDefinitions="Auto,*"><TextBlock Text="{Binding Colors.Count,StringFormat='Avalonia.Media Colors {0}'}" FontSize="18" Margin="5"/><ScrollViewer Grid.Row="1"><ItemsControl ItemsSource="{Binding Colors}"><ItemsControl.ItemTemplate><DataTemplate><StackPanel Orientation="Horizontal" Spacing="10" Margin="5"><Rectangle Width="300" Height="30"><Rectangle.Fill><SolidColorBrush Color="{Binding Color}"/></Rectangle.Fill></Rectangle><TextBlock Text="{Binding ColorName}" Width="110"/><TextBlock Text="{Binding Color,Converter={StaticResource ColorToHex},ConverterParameter={x:True}}" Width="80"/><TextBlock Text="{Binding Color,Converter={x:Static vm:ColorsViewModel.ToCMYK}}"/></StackPanel></DataTemplate></ItemsControl.ItemTemplate></ItemsControl></ScrollViewer></Grid>
</UserControl>

再建AboutView。

<UserControl xmlns="https://github.com/avaloniaui"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:vm="using:BasicRoutingExample.ViewModels"mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="560"			 x:DataType="vm:AboutViewModel"x:Class="BasicRoutingExample.Views.AboutView"><Grid RowDefinitions="Auto,Auto"><StackPanel Orientation="Horizontal" Spacing="5" Grid.Row="0"><TextBlock Text="{Binding AppName}" FontWeight="Bold" FontSize="24"/><TextBlock Text="{Binding Version}" FontSize="20"/></StackPanel><TextBlock Text="{Binding Message}" Grid.Row="1" FontSize="18"/></Grid>
</UserControl>

在MainWindowViewModel中实现更新页面的逻辑。

using Microsoft.Extensions.DependencyInjection;
using ReactiveUI;
using ReactiveUI.SourceGenerators;
using System.Reactive.Linq;namespace BasicRoutingExample.ViewModels
{public partial class MainWindowViewModel : ViewModelBase{[Reactive]private ViewModelBase? _currentPage;    [ReactiveCommand]private void GotoColors(){if(CurrentPage is not ColorsViewModel){CurrentPage = App.Current.Services?.GetRequiredService<ColorsViewModel>();}}[ReactiveCommand]private void GotoAbout(){if(CurrentPage is not AboutViewModel){CurrentPage = App.Current.Services?.GetRequiredService<AboutViewModel>();}}public MainWindowViewModel(){CurrentPage = App.Current.Services?.GetRequiredService<ColorsViewModel>();_isColorsPage = this.WhenAnyValue(x => x.CurrentPage).Select(x => x?.GetType() == typeof(ColorsViewModel)).ToProperty(this, x => x.IsColorsPage);_isAboutPage = this.WhenAnyValue(x => x.CurrentPage).Select(x => x?.GetType() == typeof(AboutViewModel)).ToProperty(this, x => x.IsAboutPage);}private readonly ObservableAsPropertyHelper<bool> _isColorsPage;private readonly ObservableAsPropertyHelper<bool> _isAboutPage;public bool IsColorsPage => _isColorsPage.Value;public bool IsAboutPage => _isAboutPage.Value;}
}

为了实现按钮被选中的效果,Avalonia可以这样做。

<Style Selector="Button.active /template/ ContentPresenter"><Setter Property="Background" Value="{StaticResource PrimaryActiveBackground}"/><Setter Property="Foreground" Value="{StaticResource PrimaryActiveForeground}"/>
</Style>
<Button Command="{Binding GotoColorsCommand}" Classes.active="{Binding IsColorsPage}"><StackPanel Orientation="Horizontal" Spacing="15"><Image Source="/Assets/images/colors.png" Width="32"/><TextBlock Text="色   彩"/></StackPanel>
</Button>
<Button Command="{Binding GotoAboutCommand}" Classes.active="{Binding IsAboutPage}"><StackPanel Orientation="Horizontal" Spacing="15"><Image Source="/Assets/images/aboutA.png" Width="32"/><TextBlock Text="关   于"/></StackPanel>
</Button>	

把Button按钮的Classes.active绑定到一个属性上IsColorsPage或IsAboutPage,由这个属性决定按钮是否被“选中”或“激活”。当页面属性 CurrentPage 属性发生改变时,通知前面二个公开属性,我们发现要实现这样的功能,ReactiveUI要敲更多的代码。

_isColorsPage = this.WhenAnyValue(x => x.CurrentPage).Select(x => x?.GetType() == typeof(ColorsViewModel)).ToProperty(this, x => x.IsColorsPage);
_isAboutPage = this.WhenAnyValue(x => x.CurrentPage).Select(x => x?.GetType() == typeof(AboutViewModel)).ToProperty(this, x => x.IsAboutPage);

如果使用communitytoolkit.mvvm,可能只需要更少的代码。
Avalonia有一个非常轻量的转换器FuncValueConverter,不需要建一个类,把它放到ViewModel中的一个属性上就可以使用,非常非常方便。

 public static FuncValueConverter<Color, string> ToCMYK { get; } = new(color =>{double r = color.R / 255.0;double g = color.G / 255.0;double b = color.B / 255.0;double k = 1 - Math.Max(Math.Max(r, g), b);double C = k < 1 ? (1 - r - k) / (1 - k) : 0;double M = k < 1 ? (1 - g - k) / (1 - k) : 0;double Y = k < 1 ? (1 - b - k) / (1 - k) : 0;return $"C={Math.Round(C * 100, 1)}% M={Math.Round(M * 100, 1)}% Y={Math.Round(Y * 100, 1)}% K={Math.Round(k * 100, 1)}%";});

把它设置成静态属性,可以这样直接使用。
<TextBlock Text="{Binding Color,Converter={x:Static vm:ColorsViewModel.ToCMYK}}"/>
在App.axaml.cs中使用communitytoolkit.mvvm的Ioc容器。

using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Data.Core.Plugins;
using Avalonia.Markup.Xaml;
using BasicRoutingExample.ViewModels;
using BasicRoutingExample.Views;
using Microsoft.Extensions.DependencyInjection;
using System;namespace BasicRoutingExample
{public partial class App : Application{public override void Initialize(){AvaloniaXamlLoader.Load(this);            }public override void OnFrameworkInitializationCompleted(){BindingPlugins.DataValidators.RemoveAt(0);Services = ConfigureServices();if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop){desktop.MainWindow = new MainWindow{DataContext = new MainWindowViewModel(),};}            base.OnFrameworkInitializationCompleted();}public new static App Current => (App)Application.Current!;public IServiceProvider? Services { get; private set; }private static ServiceProvider ConfigureServices(){var services = new ServiceCollection();services.AddTransient<ColorsViewModel>();services.AddTransient<AboutViewModel>();return services.BuildServiceProvider();}}
}

在App.axaml中使用样式。

<Application xmlns="https://github.com/avaloniaui"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"x:Class="BasicRoutingExample.App"xmlns:local="using:BasicRoutingExample"RequestedThemeVariant="Default"><!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. --><Application.DataTemplates><local:ViewLocator/></Application.DataTemplates><Application.Resources><SolidColorBrush x:Key="PrimaryBackground">#14172D</SolidColorBrush><SolidColorBrush x:Key="PrimaryForeground">#cfcfcf</SolidColorBrush><LinearGradientBrush x:Key="PrimaryGradient" StartPoint="0%,0%" EndPoint="100%,0%"><GradientStops><GradientStop Offset="0" Color="#111214"/><GradientStop Offset="1" Color="#151E3E"/></GradientStops></LinearGradientBrush><SolidColorBrush x:Key="PrimaryHoverBackground">#333853</SolidColorBrush><SolidColorBrush x:Key="PrimaryHoverForeground">White</SolidColorBrush><SolidColorBrush x:Key="PrimaryActiveBackground">#334488</SolidColorBrush><SolidColorBrush x:Key="PrimaryActiveForeground">AliceBlue</SolidColorBrush></Application.Resources><Application.Styles><FluentTheme />				<Style Selector="TextBlock"><Setter Property="Foreground" Value="{StaticResource PrimaryForeground}"/><Setter Property="VerticalAlignment" Value="Center"/></Style><Style Selector="TextBlock.caption"><Setter Property="FontSize" Value="28"/><Setter Property="HorizontalAlignment" Value="Center"/><Setter Property="VerticalAlignment" Value="Center"/></Style><Style Selector="Border.menu"><Setter Property="Background" Value="{StaticResource PrimaryGradient}"/><Setter Property="Padding" Value="10"/></Style><Style Selector="Border.client"><Setter Property="Padding" Value="10"/><Setter Property="Background" Value="{StaticResource PrimaryBackground}"/></Style><Style Selector="Button"><Setter Property="HorizontalContentAlignment" Value="Center"/><Setter Property="Width" Value="150"/></Style><Style Selector="Button /template/ContentPresenter">						<Setter Property="Background" Value="Transparent"/><Setter Property="Foreground" Value="{StaticResource PrimaryForeground}"/><Setter Property="FontSize" Value="18"/>			</Style>		<Style Selector="Button:pointerover /template/ContentPresenter"><Setter Property="Background" Value="{StaticResource PrimaryHoverBackground}"/><Setter Property="Foreground" Value="{StaticResource PrimaryHoverForeground}"/></Style><Style Selector="Button.active /template/ ContentPresenter"><Setter Property="Background" Value="{StaticResource PrimaryActiveBackground}"/><Setter Property="Foreground" Value="{StaticResource PrimaryActiveForeground}"/></Style></Application.Styles>
</Application>
http://www.sczhlp.com/news/94321/

相关文章:

  • 什么网站上做推广效果比较好重庆装修平台
  • 电子商务网站建设与电子支付手机网站做桌面快捷方式
  • 深圳建网站一般多少钱公司名称logo图片
  • 买一个成品网站多少钱网页设计作品集图片
  • 如何做网站搬运工赚钱自然志wordpress免费
  • 网站描述 关键词用以前用过的域名做网站
  • 西安哪家网站建设公司好宁夏众擎达网站建设
  • 企业网站定制开发流程网页设计模板素材代码
  • bashrc的一些配置记录
  • H5游戏性能优化系列-----协议相关优化
  • 包做包装的网站做网站头文件
  • 新乡网站建设哪家专业西安网站建设企业
  • 实现我的第一个langchain应用
  • 网站内容框架公司门户网站首页
  • 制作网页的模板的网站网站建设mfdos 优帮云
  • 学做宝宝衣服的网站随州程力网站建设
  • 网站运营总结网站开发培训费用
  • 网站管理系统后台软文怎么写
  • 网站软件下载安装雏鸟短视频app软件下载网站
  • 添加网站栏目的步骤库存网站建设定制
  • 广东省建设安全监督站的网站网站开发 上海
  • 做网站 信息集成过程的顺序网络项目免费的资源网
  • c 网站开发 环境配置兰州软件公司排名
  • 网站开发的背景意义免费建网站
  • 怎么学做网站世界工厂网登录
  • 家具网站模板网站后台管理系统安装
  • 甜品网站模板代码上海展览公司
  • 上海网站设计公司有哪些罗湖商城网站设计多少钱
  • 南宁百度网站公司吗网站前台功能
  • 湖南广源建设工程有限公司网站企业邮箱是怎么样的