是否可以在视图模型中包含方法,还是应该将它们放置在代码的另一部分中?

时间:2019-06-23 09:10:08

标签: xamarin xamarin.forms

我的Xamarin表单ViewModel看起来像这样:

public class CFSPageViewModel : BaseViewModel
{
    #region Constructor

    public CFSPageViewModel()
    {
        PTBtnCmd = new Command<string>(PTBtn);
        OnTappedCmd = new Command<string>(OnTapped);
    }

    #endregion

    # region Commands

    public ICommand PTBtnCmd { get; set; }
    public ICommand OnTappedCmd { get; }

    #endregion

    #region Methods

    private void OnTapped(string btnText)
    {
        Utils.SetState(btnText, CFS, SET.Cfs);
        CFSMessage = Settings.cfs.TextLongDescription();
    }

    private void PTBtn(string btnText)
    {
        Utils.SetState(btnText, PT);
        SetLangVisible(btnText);
        SetLangSelected(btnText);
        CFSMessage = Settings.cfs.TextLongDescription();
    }


}

我以前使用MessageCenter将消息发送到我的C#后端代码,但现在已删除MessageCenter,因此这些方法是ViewModel的一部分。

这是安全的事吗?我听说在ViewModels之间传递的所有MessageCenter消息并不是最好的解决方案。

请注意,这是我之前做过的事情:

MyPageViewModel.cs

PTBtnCmd = new Command<Templates.WideButton>((btn) =>             
              MessagingCenter.Send<CFSPageViewModel, Templates.WideButton>(
              this, "PTBtn", btn));

MyPage.xaml.cs

MessagingCenter.Subscribe<CFSPageViewModel, Templates.WideButton>(
        this, "PTBtn", (s, btn) =>
        {
            Utils.SetState(btn.Text, vm.PT);
            SetLangVisible(btn.Text);
            SetLangSelected(btn.Text);
            vm.CFSMessage = Settings.cfs.TextLongDescription();
        });

请注意,MyPage.xaml.cs中也包含SetLangVisible之类的方法

1 个答案:

答案 0 :(得分:4)

只需将事件处理程序添加到您的Button

<ContentPage
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="MyProject.Views.MyPage">
    <ContentPage.Content>
        <StackLayout>
            <Button Text="PTBtn" Clicked="Handle_Clicked" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

在后面的代码中:

namespace MyProject.Views
{
    public partial class MyPage : ContentPage
    {
        public MyPage()
        {
            InitializeComponent();
        }
        void Handle_Clicked(object sender, EventArgs eventArgs)
        {
            ((Button)sender).BackgroundColor = Color.Blue; // sender is the control the event occured on

            // Here call your methods depending on what they do/if they are view related
            /*
            Utils.SetState(btn.Text, vm.PT);
            SetLangVisible(btn.Text);
            SetLangSelected(btn.Text);
            vm.CFSMessage = Settings.cfs.TextLongDescription();
            */
        }
    }
}

所有可以为其分配事件处理程序的事件以黄色列出,并带有E: enter image description here


Command首先触发,您可以在构造函数中添加CanExecute作为第二个参数-这也将停止执行命令和事件处理程序。

我还将Command重命名为SelectLanguageCommand之类-以便将它与ui操作区分开。这样,您可以断开按钮与命令的连接,并将命令连接到其他ui-如果您决定将来更改视图。在进行单元测试时,也将更容易理解。


  

这是安全的事吗?我听说在ViewModels之间传递的所有MessageCenter消息并不是最佳解决方案。

您可以向DependencyService注册所有视图模型

public App()
{
    InitializeComponent();

    DependencyService.Register<AboutViewModel>();
    DependencyService.Register<CFSPageViewModel>();
    DependencyService.Register<MyPageViewModel>();
    MainPage = new AppShell();
}

将视图的BindingContext设置为已注册的实例:

public AboutPage()
{
    InitializeComponent();
    BindingContext = DependencyService.Get<AboutViewModel>();
}

并在需要的任何位置获取ViewModel实例。这样一来,您使用MessagingCenter时就不必处理订阅。

是否安全-我不确定。