gpt4 book ai didi

mvvm - Xamarin.Forms:是否可以在没有 ViewModel 调用 VIew 的情况下将行动态添加到网格中?

转载 作者:行者123 更新时间:2023-12-03 11:02:52 25 4
gpt4 key购买 nike

在我向用户显示收据的页面上,我有一个部分列出了小计、任何税金和总计。由于适用的税费因地区和所售产品而异,因此本节中的行数会有所不同。例如,这里有 3 个单独的订单,一个包含 GST 和 PST,一个只有 GST,一个没有:

GST+PST

GST Only

No Tax

我通过将 SubTotal 放在 XAML 中的网格中,并将其余部分添加到我从 ViewModel 调用的方法中的代码隐藏中来实现这一点。但是,我真的很想避免这样做,所以我想知道是否有一种不需要让 ViewModel 知道 View 的方法来完成这个。

一个 ListView不适合这里有几个原因:

  • 这些控件位于 ScrollView 中。 ,并且有一个 ListView ScrollView 的内部导致各种奇怪的问题。
  • 我想保持列与其最宽的元素一样窄。这可以通过 Grid , 但是一个 ListView无论如何都会占据其父级的整个宽度。
  • 我既不需要也不希望我的行可以选择

  • 那么有没有一种方法可以在 ViewModel 不知道 View 并且不使用 ListView 的情况下做到这一点? ?

    最佳答案

    封装所需功能以使 View 和 View 模型不耦合的一种方法是创建用户控件。

    我创建了一个名为 TotalsGridControl 的新用户控件。这是 XAML

    <?xml version="1.0" encoding="UTF-8"?>
    <Grid xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="ScratchPad.UserControls.TotalsGridControl"
    x:Name="TotalsGrid">

    <Grid.ColumnDefinitions>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>

    </Grid>

    这是背后的代码。
    public partial class TotalsGridControl : Grid
    {
    public TotalsGridControl()
    {
    InitializeComponent();
    }

    public static readonly BindableProperty TotalsProperty =
    BindableProperty.Create(nameof(Totals), typeof(List<TotalItem>), typeof(TotalsGridControl), null,
    BindingMode.OneWay, null, OnTotalsChanged);

    private static void OnTotalsChanged(BindableObject bindable, object oldvalue, object newvalue)
    {
    var control = (TotalsGridControl)bindable;
    if (control != null)
    {
    if (newvalue is List<TotalItem> totals)
    {
    var rowNumber = -1;
    double grandTotal = 0;

    foreach (var totalItem in totals)
    {
    grandTotal += totalItem.Value;

    var descLabel = new Label {Text = totalItem.Description};
    var valueLabel = new Label { Text = totalItem.Value.ToString("c") };

    rowNumber++;
    control.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto});
    control.Children.Add(descLabel, 0, rowNumber);
    control.Children.Add(valueLabel, 1, rowNumber);
    }

    var grandTotalDescLabel = new Label { Text = "Total" };
    var grandTotalValueLabel = new Label { Text = grandTotal.ToString("c") };

    rowNumber++;
    control.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
    control.Children.Add(grandTotalDescLabel, 0, rowNumber);
    control.Children.Add(grandTotalValueLabel, 1, rowNumber);
    }
    }
    }

    public List<TotalItem> Totals
    {
    get => (List<TotalItem>)GetValue(TotalsProperty);
    set => SetValue(TotalsProperty, value);
    }
    }

    我使用了一个可绑定(bind)属性来允许将 TotalItem 列表绑定(bind)到用户控件。

    这是 View 模型中的数据
    public List<TotalItem> Totals { get; set; }

    Totals = new List<TotalItem>
    {
    new TotalItem {Description = "SubTotal", Value = 99.91},
    new TotalItem {Description = "GST", Value = 5.0},
    new TotalItem {Description = "PST", Value = 4.9}
    };

    这是页面中的 XAML
    <userControls:TotalsGridControl Totals="{Binding Totals}"/>

    和输出

    enter image description here

    关于mvvm - Xamarin.Forms:是否可以在没有 ViewModel 调用 VIew 的情况下将行动态添加到网格中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47706040/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com