微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ViewModel 是否应该继承 Xamarin.Forms 中的其他 ViewModel?

如何解决ViewModel 是否应该继承 Xamarin.Forms 中的其他 ViewModel?

应该{​​{1}}继承其他viewmodels吗?

我有一个 viewmodels,其中包含 Merchandiserviewmodel 模型的基本属性数据库函数

Merchandiser 具有 Merchandiserviewmodel 属性,该属性SelectedMerchandiser 中选定的 Merchandiser 保存在 ItemSelected

Merchandiserviewmodel.cs

ListView

public Merchandiserviewmodel : INotifyPropertyChanged { // Property to hold the selected Merchandiser // Generally I would make this static but then I can't bind the property public Merchandiser SelectedMerchandiser {get; set;} // Other logic... } Merchandiserviewmodel 中被实例化为 Static Resource,因此我只有一个视图模型实例。

App.xaml

App.xaml

对于与销售商相关的每个 <?xml version="1.0" encoding="utf-8" ?> <Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="MobileApp.App" xmlns:viewmodels="clr-namespace:MobileApp.viewmodels"> <Application.Resources> <viewmodels:Merchandiserviewmodel x:Key="Merchandiserviewmodel" /> <viewmodels:MerchandiserProfileviewmodel x:Key="MerchandiserProfileviewmodel" /> </Application.Resources> </Application> ,例如ViewMerchandiserProfile 等。我创建了一个新的 EditProfile 并继承了 viewmodel

MerchandiserProfileviewmodel.cs 继承 Merchandiserviewmodel

Merchandiserviewmodel

问题是...当我创建一个新的 public class MerchandiserProfileviewmodel : Merchandiserviewmodel { // Logic Specific to the Merchandiser Profile View } 并继承“Merchandiserviewmodel”时,我收到以下错误消息。

Error Message

我认为这可能是因为创建了 [Page]viewmodel 的新实例,所以我没有引用初始 Merchandiserviewmodel 属性

这让我觉得继承 viewmodels 不是一个好主意?

这种情况一般是怎么处理的?我应该将每个页面/视图的所有逻辑都塞进一个 SelectedMerchandiser 中吗?我希望我的代码尽可能干净和分离,因此希望尽可能避免这种情况。

经过深思熟虑 我可以在 C# 中访问静态资源中 Merchandiserviewmodel属性吗?这样我就可以在不继承 Merchandiserviewmodel 的情况下将所需的属性传递给新的 viewmodel ... 想听听对此的想法吗?

解决方法

MerchandiserViewModel 有一个 SelectedMerchandiser 属性,该属性保存了 ListView 中 ItemSelected 中选定的 Merchandiser

根据你的描述,你要绑定ListView,MerchandiserViewModel,你不需要继承其他的ViewModel,建议你看看the Model-View-ViewModel Pattern

我做了一个使用 MVVM 绑定 ListView 的示例,请看一下。

<StackLayout>
        <ListView
            x:Name="listview1"
            HasUnevenRows="True"
            ItemsSource="{Binding mers}"
            SelectedItem="{Binding selecteditem}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout>
                            <Label
                                FontSize="Large"
                                Text="{Binding Name}"
                                VerticalOptions="Center" />

                            <Label
                                FontSize="Small"
                                Text="{Binding PhoneNumber}"
                                VerticalOptions="Center" />
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>

模型类,包含一些绑定到 UI 的属性。

 public class Merchandiser
{
    public string Name { get; set; }    
    public string PhoneNumber { get; set; }
    
}

MerchandiserViewmodel 类,视图模型实现视图可以数据绑定到的属性和命令,并通过更改通知事件通知视图任何状态更改。视图模型提供的属性和命令定义了 UI 提供的功能,但视图决定了该功能的显示方式。

 public class MerchandiserViewmodel:ViewModelBase
{
    public ObservableCollection<Merchandiser> mers { get; set; }
    private Merchandiser _selecteditem;
    public Merchandiser selecteditem
    {
        get { return _selecteditem; }
        set
        {
            _selecteditem = value;
            RaisePropertyChanged("selecteditem");
        }
    }
    public MerchandiserViewmodel()
    {
        mers = new ObservableCollection<Merchandiser>();
        getdata();
    }
    private void getdata()
    {
        for(int i=0;i<20;i++)
        {
            Merchandiser mer = new Merchandiser();
            mer.Name = "merchandiser "+i;
            mer.PhoneNumber = "123";
            mers.Add(mer);

        }
    }
}

ViewModelBase 是实现 INotifyPropertyChanged 接口的类,通知数据发生变化。对于 MerchandiserView 模型,Selected Merchandiser(selecteditem) 必须实现 INotifyPropertyChanged 以在您每次从 ListView 中选择项目时通知数据更改。

public class ViewModelBase : INotifyPropertyChanged
{
   
    public event PropertyChangedEventHandler PropertyChanged;

   
    public void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this,new PropertyChangedEventArgs(propertyName));
        }
    }
}

将 ViewModel 绑定到 ContentPage

 public partial class Page10 : ContentPage
{
    public Page10()
    {
        InitializeComponent();
        this.BindingContext = new MerchandiserViewmodel();
    }
}

更新:

如果您想在选择 ListView 项时导航到详细页面,可以在 ListView_ItemSelected 事件中使用构造函数传递值。

<StackLayout>
        <ListView
            x:Name="listview1" ItemSelected="listview1_ItemSelected" SelectionMode="Single"
            HasUnevenRows="True"
            ItemsSource="{Binding mers}"
            SelectedItem="{Binding selecteditem}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout>
                            <Label
                                FontSize="Large"
                                Text="{Binding Name}"
                                VerticalOptions="Center" />

                            <Label
                                FontSize="Small"
                                Text="{Binding PhoneNumber}"
                                VerticalOptions="Center" />
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>

  private async void listview1_ItemSelected(object sender,SelectedItemChangedEventArgs e)
    {
        Merchandiser item = (Merchandiser)e.SelectedItem;
       await Navigation.PushAsync(new simplecontrol.Page29(item));
    }

详细页面:

<ContentPage.Content>
    <StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="Name: " />
            <Label
                FontSize="Large"
                Text="{Binding Name}"
                VerticalOptions="Center" />
        </StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="PhoneNumber: " />
            <Label
                FontSize="Small"
                Text="{Binding PhoneNumber}"
                VerticalOptions="Center" />
        </StackLayout>


    </StackLayout>
</ContentPage.Content>

public partial class Page29 : ContentPage
{
    public Page29(Merchandiser mer)
    {
        InitializeComponent();
        this.BindingContext = mer;
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。