Mvvm - 模型类 - 从类中访问私有成员和属性的“最佳”方法是什么? [英] Mvvm - model class - what is 'best' way of accessing private members and properties from within the class?

查看:65
本文介绍了Mvvm - 模型类 - 从类中访问私有成员和属性的“最佳”方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好!



这是第一个问题,所以对我这么简单! ;-)另外请记住,我是VS和VB的初学者,现在使用它半年了。原谅我,如果我使用错误的条款,还是很新的。



情况:

我正在开发一个vb.net桌面应用程序在VS2017中使用MVVM模式。仍然学习很多,但取得了很好的进展,这里读了很多文章!



到目前为止,我有我的UI层(Windows,用户控件和界面的组合) ),ViewModes和数据模型。仍然必须制作数据访问层(或在数据模型中实现,尚不确定)。



一般问题:

一方面我很难理解何时使用私有字段vs 类本身内的私有字段的属性。使用搜索但没有找到合适的答案。是仅使用属性成员进行绑定的最佳方法还是没有一般规则?



示例:

模型类Person具有Default Ctor New()并实现INotifyPropertyChanged和INotifyDataErrorInfo(通过基类)。我使用默认的Ctor,因为我想要设计时数据。

在New()中我设置属性成员(Number和Name)而不是私有成员(_number和_name)。通过这种方式触发事件。在我的VM中实例化Person类并在我的用户控件中使用Bindings(以及一些XAML的东西)时,在显示window / uc(设计选项)时,我会收到错误消息的提示。设置按钮(使用中继命令绑定)并进行更新。到目前为止,这个工作完美,编程感觉很好。



具体问题:

然后,当我加载一个列表(函数)模型类中的共享GetList())当使用默认Ctor时,为每个新记录触发事件(如果我在GetList()中设置属性,它们甚至会被第二次触发)。因此,为了加载列表,我创建了第二个设置私有成员的Ctor New()。因为当我不需要它们时,所有这些事件都被解雇会感觉错误。



这样可以吗?使用一个Ctor进行初始化,使用一个Ctor进行加载。或者我应该改变使用私有成员和属性的方式吗?



也可以随意发表关于我的MVVM实现的想法。我不打算采用MVVM纯粹主义方法,我是一个单一的开发人员,并且会保持这种状态。但是我使用的方法有哪些主要缺点,还是有更好的方法? (或者我应该为此提出一个新问题?)



(发布时我没有看到要选择的部分,希望它最终出现在正确的位置)



我尝试过:



创建默认Ctor并设置属性

创建第二个Ctor并设置私有字段

Hi All!!

First question here, so go easy on me people! ;-) Also keep in mind, I'm a beginner with VS and VB, using it for a half year now. Forgive me if I use wrong terms, still very new to this.

Situation:
I'm developing a vb.net desktop app in VS2017 using the MVVM pattern. Still learning a lot but making good progress, thx to reading a lot of articles here!

So far I have my UI layer (combination of Windows, User Controls and Interfaces), ViewModes and Data Models. Still have to make the Data Access layer (or implement this within the Data Model, not sure yet).

General problem:
One aspect I have a hard time to "understand" is when to use the private field vs the property of that private field within the class itself. Used the search but didn't find appropriate answers. Is the best approach to use the property members ONLY for the binding or is there no "general rule"?

Example:
Model Class Person has the Default Ctor New() and implements the INotifyPropertyChanged and INotifyDataErrorInfo (through base class). I use the default Ctor because I want designtime data.
Within New() I set the property members (Number and Name) and not the private members (_number and _name). This way the Events are fired. When instantiating a Person class in my VM and using the Bindings in my User Control (and some XAML stuff) I get nice hints with the error messages when showing the window/uc (design choice). Buttons (binding with relay commands) are set and get updated. So far this works perfect and programming it "feels" good.

Specific problem:
But then, when I load a list (function Shared GetList() in Model Class) the events are fired for every new record when using the Default Ctor (and if I set properties within the GetList() they even get fired a second time). So for loading the list I created a second Ctor New() that sets the private members. Because it feels "wrong" that all those events get fired when I don't need them.

Is this okay to do? Use one Ctor for 'initialising' and one Ctor for "loading". Or should I change the way I use Private members and Properties?

Also feel free to post your thought about "my" MVVM implementation. I'm not going for a MVVM purist approach, I'm a single developer and that will stay that way. But are there major disadvantages about the approach I use or is there a better approach? (Or should I make a new question for this?)

(When posting this I didn't see a section to choose, hope it ends up in the right place)

What I have tried:

Create default Ctor and set the Properties
Create a second Ctor and set the Private Fields

推荐答案

使用属性访问私有字段的一般想法class是能够将它设置在该类之外,因此属性具有公共访问修饰符。

使用该属性访问类中的私有变量是没有意义的。只需使用变量。此外,您也不需要调用构造函数。如果您正在使用双向绑定,那么当您更新属性时,它将自动反映在视图中。这就是MVVM模式的美妙之处。

您需要做的就是通知该属性已更新的视图。
The general idea of having a property to access a private field of a class is to be able to set it outside of that class and hence properties have the "Public" access modifier.
There is no point using the property to access a private variable within the class. Just use the variable. Also, you do not need to call the constructor either. If you're using two-way binding then when you update the property it will automatically be reflected in the view. That is the beauty of the MVVM pattern.
All you need to do is "notify" the view that the property has been updated.


引用:

模型 - 视图 - ViewModel(MVVM)是一种软件架构模式。



MVVM便利通过业务逻辑或后端逻辑(数据模型)的开发,分离图形用户界面的开发 - 无论是通过标记语言还是GUI代码。 MVVM的视图模型是一个值转换器,[1]意味着视图模型负责从模型中公开(转换)数据对象,以便轻松管理和呈现对象。在这方面,视图模型比视图更具模型,并且处理大多数(如果不是全部)视图的显示逻辑。[1]视图模型可以实现一个中介模式,组织对视图支持的一组用例的后端逻辑的访问。

Model–View–ViewModel (MVVM) is a software architectural pattern.

MVVM facilitates a separation of development of the graphical user interface – be it via a markup language or GUI code – from development of the business logic or back-end logic (the data model). The view model of MVVM is a value converter,[1] meaning the view model is responsible for exposing (converting) the data objects from the model in such a way that objects are easily managed and presented. In this respect, the view model is more model than view, and handles most if not all of the view's display logic.[1] The view model may implement a mediator pattern, organizing access to the back-end logic around the set of use cases supported by the view.

ref:模型 - 视图 - 视图模型 - 维基百科 [ ^ ]



WPF通过数据绑定 [ ^ ]。



我是一名独立软件开发人员,我发现MVVM模式以及MEF是一个非常有用的模式。



但是,听起来你不想使用MVVM模式但想要使用数据绑定系统。那也没关系。下面是使用没有MVVM模式的数据绑定的示例:



XAML页面:

ref: Model–view–viewmodel - Wikipedia[^]

WPF makes this possible via Data Binding[^].

I am an independent software developer and I find the MVVM pattern, along with MEF, a very useful pattern to adhere to.

However, it sounds like you don't want to use the MVVM pattern but want to use the data binding system. That is fine too. Here is an example of using Data Binding without the MVVM Pattern:

XAML Page:

<Window x:Class="WpfSimpleBinding.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"



        mc:Ignorable="d"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"



        xmlns:local="clr-namespace:WpfSimpleBinding"



        Title="Basic code-behin binding example"

        WindowStartupLocation="CenterScreen" Height="400" Width="300">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <Grid.Resources>
            <DataTemplate DataType="{x:Type local:PersonModel}">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="{Binding Name}" Margin="10 3"/>
                    <TextBlock Text="{Binding Age}" Margin="10 3"

                               Grid.Column="1"/>
                </Grid>
            </DataTemplate>
        </Grid.Resources>

        <ListBox ItemsSource="{Binding Persons}">
            <ListBox.ItemContainerStyle>
                <Style TargetType="ListBoxItem">
                    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                </Style>
            </ListBox.ItemContainerStyle>
        </ListBox>
        <Button Content="Randomize" Padding="10 5" Margin="10"

                HorizontalAlignment="Center" VerticalAlignment="Center"

                Grid.Row="1" Click="Button_Click"/>
    </Grid>

</Window>



基本 INotifyPropertyChanged 实现(可重复使用):


Base INotifyPropertyChanged implementation (reusable):

public abstract class ObservableBase : INotifyPropertyChanged
{
    public void Set<TValue>(ref TValue field, TValue newValue, [CallerMemberName] string propertyName = "")
    {
        if (EqualityComparer<TValue>.Default.Equals(field, default(TValue)) || !field.Equals(newValue))
        {
            field = newValue;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}



数据模型:


Data Model:

public class PersonModel : ObservableBase
{
    private string name;
    public string Name
    {
        get { return name; }
        set { Set(ref name, value); }
    }

    private int age;
    public int Age
    {
        get { return age; }
        set { Set(ref age, value); }
    }
}



和XAML页面的代码隐藏:


and the Code-Behind for the XAML Page:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        Mock();
    }

    public ObservableCollection<PersonModel> Persons { get; set; }
        = new ObservableCollection<PersonModel>();

    private Random rand = new Random();

    private void Mock()
    {
        for (int i = 0; i < 10; i++)
        {
            Persons.Add(new PersonModel
            {
                Name = string.Format("Person {0}", i),
                Age = rand.Next(20, 50)
            });
        }
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        foreach (var person in Persons)
        {
            person.Age = rand.Next(20, 50);
        }
    }
}



我们正在使用WPF数据绑定的传统(winform样式)控件事件。 MVVM模式解决的缺点是代码隐藏(ViewModel)紧密绑定到XAML页面和控件。


We are using traditional (winform style) control events with WPF Data Binding. The downside of this, that the MVVM pattern resolves, is that the code-behind (ViewModel) is tightly bound to the XAML page and controls.


这篇关于Mvvm - 模型类 - 从类中访问私有成员和属性的“最佳”方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆