【问题标题】:How to organize a MVVM pattern?如何组织一个 MVVM 模式?
【发布时间】:2022-10-03 01:38:41
【问题描述】:

我有两个模型。

public class Model1
{
    public type Property1 { get; set; }
    public type Property2 { get; set; }
    public type Property3 { get; set; }
}

public class Model2
{
    public type Property1 { get; set; }
    public type Property2 { get; set; }
    public List<Model1> List { get; set; }
    public type Property4 { get; set; }
}

Property4 的值取决于List 元素的属性。例如最大值或平均值。

我还有DetailsModel2Page,它在屏幕上显示Model2 的所有属性。在此页面上,我可以更改 List 元素的属性。由于Property4 依赖于这些属性,所以它的值将会改变。 Model1.Property1Model1.Property2Model1.Property3Model2.Property4的变化必须更新UI。

在这种情况下,我该如何设计模型、视图和视图模型?

  • 请尽可能多地实施这一点。例如,“...的更改必须更新 UI” 是简单的 MVVM / 数据绑定,在相应的 Maui 文档中进行了介绍,以及针对 xamarin 表单的无数示例和问题。达到一个你可以问“我应该在 xaml/c# 中放什么?”的地步,其中“这里”是一个具体细节你被卡住了。 stackoverflow.com/help/how-to-ask
  • 对我来说,听起来您可能想了解更多关于 MVVM 的信息,并且可能会通过一些示例:learn.microsoft.com/en-us/dotnet/architecture/maui/mvvm

标签: mvvm maui


【解决方案1】:

Model1.Property1、Model 1.Property 2、Model1.Property 3 的变化 并且 Model2.Property 4 必须更新 UI。

对于这个问题,您可以为类Model1 实现接口INotifyPropertyChanged,并对其中的每个属性进行以下更改。一旦更改其属性的值,UI 将自动更新。

public class Model1: INotifyPropertyChanged
    {
       // public string Property1 { get; set; }

        int  _property1;
        public int Property1
        {
            set {

                SetProperty(ref _property1, value);

                getAverageValue(Property1);
            }

            get { return _property1; }
        }

        private void getAverageValue(int parameter)
        {
            System.Diagnostics.Debug.WriteLine("------> message is sended   ");
            MessagingCenter.Send<object>(this, "Hi");
        }



        // public string Property2 { get; set; }
        string _property2;
        public string Property2
        {
            set { SetProperty(ref _property2, value); }

            get { return _property2; }
        }


        // public string Property3 { get; set; }

        string _property3;
        public string Property3
        {
            set { SetProperty(ref _property3, value); }

            get { return _property3; }

        }


        bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
        {
            if (Object.Equals(storage, value))
                return false;

            storage = value;
            OnPropertyChanged(propertyName);
            return true;
        }

        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

Property4 的值取决于 List 元素的属性。为了 例如最大值或平均值。

在这里,您还需要为类Model2 实现接口INotifyPropertyChanged 并更改属性Property4

在此页面上,我可以更改列表元素的属性。自从 Property4 依赖于这些属性,它的值会改变

这里,List的元素属性值发生变化后需要通知Property4 属性值,可以试试MessagingCenter

我创建了一个demo并实现了这个,你可以参考以下代码:

public class Model2: INotifyPropertyChanged
    {
        public string Property1 { get; set; }
        public string Property2 { get; set; }
        public List<Model1> List { get; set; }

        //public string Property4 { get; set; }
        int _property4;
        public int Property4
        {
            set
            {

                SetProperty(ref _property4, value);

            }

            get { return _property4; }
        }

        public Model2() {

            List = new List<Model1>();

            List.Add(new Model1 { Property1 = 1 ,Property2="test"}) ;
            List.Add(new Model1 { Property1 = 2, Property2 = "test" });
            List.Add(new Model1 { Property1 = 3, Property2 = "test" });
            List.Add(new Model1 { Property1 = 4, Property2 = "test" });
            List.Add(new Model1 { Property1 = 5, Property2 = "test" });
            List.Add(new Model1 { Property1 = 6 , Property2 = "test" });

            // get the average value for Property4 
            calculateAverage();

            MessagingCenter.Subscribe<object>(this, "Hi", (sender) =>
            {
                // Do something whenever the "Hi" message is received
                System.Diagnostics.Debug.WriteLine("------> message is received   ");
                calculateAverage();

            });
        }

        public void calculateAverage() {
            int sum = 0;

            foreach (Model1 model in List)
            {
                sum += model.Property1;
            }

            Property4 = sum / List.Count;
        }

        bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
        {
            if (Object.Equals(storage, value))
                return false;

            storage = value;
            OnPropertyChanged(propertyName);
            return true;
        }

        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

详细信息Model2Page.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiApp102.DetailsModel2Page"
             Title="DetailsModel2Page">
    <VerticalStackLayout>


        <ListView  x:Name="lstView" RowHeight="60" ItemsSource="{Binding List}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout Orientation="Horizontal" HorizontalOptions="Fill" BackgroundColor="Olive">
                            <StackLayout Orientation="Vertical">
                                <Entry Text = "{Binding Property1,Mode=TwoWay}"      FontSize="24" AbsoluteLayout.LayoutBounds="0.25, 0.25, 400, 40"/>
                                <Label Text = "{Binding Property2}" AbsoluteLayout.LayoutBounds="50, 35, 200, 25"/>
                            </StackLayout>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <Label
            Text="{Binding Property4}"
            VerticalOptions="Center"
            HorizontalOptions="Center" />
    </VerticalStackLayout>
</ContentPage>

详细信息Model2Page.xaml.cs

public partial class DetailsModel2Page : ContentPage
{
      public DetailsModel2Page()
      {
            InitializeComponent();

            BindingContext = new Model2();
      }
}

【讨论】:

    猜你喜欢
    • 2021-06-09
    • 1970-01-01
    • 2021-12-07
    • 1970-01-01
    • 2012-06-03
    • 2016-08-12
    • 1970-01-01
    • 2019-09-29
    • 1970-01-01
    相关资源
    最近更新 更多