使用 ReactiveUI 在视图模型中绑定和操作用户控件属性的最佳实践是什么?

问题描述 投票:0回答:1

来自网络世界,您可以出于多种原因轻松创建可重用组件。许多可重用组件允许您操作从父上下文中的 set 给出的数据属性。例如:

<IncrementButton startCount={1} title="My Title" />

enter image description here

当用户单击增量按钮时,计数会增加一。

但是假设我想要第 2 页上的相同组件,但我希望 startCount 从 2 开始,并具有不同的标题:

<IncrementButton startCount={2} title="Hello World" />

enter image description here

在第二张图片中,计数从 2 开始,并在第一次增量单击时增加到 3。

当数据通过属性传递时,使用 ReactiveUI/Avalonia 操作数据的最佳实践是什么:

第一页

<control:IncrementButton Count="1" Title="My Title" />

第二页

<control:IncrementButton Count="2" Title="Hello World" />

我是否像这样将控件传递给视图模型?

public class IncrementButton : UserControl
{
    public static readonly StyledProperty<int> CountProperty =
        AvaloniaProperty.Register<MyButtonView, int>(nameof(Count));

    public int Count
    {
        get => GetValue(CountProperty);
        set => SetValue(CountProperty, value);
    }

    public IncrementButton()
    {
        InitializeComponent();

        // Set DataContext to a new instance of the ViewModel
        DataContext = new IncrementButtonViewModel(this); // Pass the control itself to the ViewModel
    }
}

如何连接绑定来操纵视图模型中的起始计数?

data-binding reactiveui avaloniaui avalonia
1个回答
0
投票

Avalonia 模板化控件更适合您的需求

TemplatedControls 最适合用于可以在各种应用程序之间共享的通用控件。

在控件文件夹中从 avalonia 模板创建模板化控件(仅将所有控件聚合在单个文件夹中)

IncrementButton.axaml.cs

public class IncrementButton : TemplatedControl
{
    public static readonly StyledProperty<int> CountProperty =
        AvaloniaProperty.Register<IncrementButton, int>(
            nameof(Count),
           defaultBindingMode: BindingMode.TwoWay);

    public static readonly StyledProperty<string> TitleProperty =
        AvaloniaProperty.Register<IncrementButton, string>(
            nameof(Count),
            defaultValue: "");

    public string Title
    {
        get => GetValue(TitleProperty);
        set => SetValue(TitleProperty, value);
    }
    public int Count
    {
        get => GetValue(CountProperty);
        set => SetValue(CountProperty, value);
    }


    protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
    {
        var btn = e.NameScope.Find<Button>("Increment_btn");
        if (btn is not null)
            btn.Click += (s, e) => Count++;
    }
}

增量按钮.axaml

<ResourceDictionary xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:controls="using:AvaloniaApplication5.Controls">
  
  <Design.PreviewWith>
    <StackPanel Width="400" Spacing="10">
          <controls:IncrementButton Title="test title" />
    </StackPanel>
  </Design.PreviewWith>
 
  <ControlTheme x:Key="{x:Type controls:IncrementButton}" TargetType="controls:IncrementButton">
    <Setter Property="Template">
      <ControlTemplate>
        <Grid RowDefinitions="auto,auto">
          <Grid.Styles>
            <Style Selector="TextBlock">
              <Setter Property="VerticalAlignment" Value="Center"/>
            </Style>
            <Style Selector="TextBlock.Title">
              <Setter Property="FontSize" Value="18"/>
              <Setter Property="FontWeight" Value="Bold"/>
              <Setter Property="Foreground" Value="#A45E0E"/>
              <Setter Property="Margin" Value="0 10 0 10"/>
            </Style>
            <Style Selector="Button#Increment_btn">
              <Setter Property="Background" Value="Transparent"/>
              <Setter Property="BorderBrush" Value="#6798DA"/>
              <Setter Property="Foreground" Value="#6798DA"/>
              <Setter Property="Cursor" Value="Hand"/>
              <Setter Property="Padding" Value="20 10"/>
              <Setter Property="Margin" Value="0 0 20 0"/>
              <Style Selector="^:pointerover /template/ContentPresenter">
                <Setter Property="Background" Value="Transparent"/>
                <Setter Property="BorderBrush" Value="#6798DA"/>
                <Setter Property="Foreground" Value="#6798DA"/>
              </Style>
            </Style>
          </Grid.Styles>
          
          <TextBlock Classes="Title" Text="{TemplateBinding Title}" />
          <StackPanel  Grid.Row="1" Orientation="Horizontal" Margin="0 0 0 10">
            <Button Name="Increment_btn" Content="increment"  />
            <TextBlock Text="count:"/>
            <TextBlock Text="{TemplateBinding Count}"/>
          </StackPanel>
        </Grid>
      </ControlTemplate>
    </Setter>
  </ControlTheme>
</ResourceDictionary>

将此控件添加到您的应用程序中的 App.axaml

<Application.Resources>
  <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
      <ResourceInclude Source="/Controls/IncrementButton.axaml"/>
    </ResourceDictionary.MergedDictionaries>
  </ResourceDictionary>
</Application.Resources>

如何使用

<StackPanel>
  <controls:IncrementButton Title="My Title" Count="1" />
  <controls:IncrementButton Title="Hello World" Count="2" />
  <controls:IncrementButton Title="bla bla" Count="-5" />
</StackPanel>

结果

Rendered result image

© www.soinside.com 2019 - 2024. All rights reserved.