如何从VM管理表单控件?

时间:2012-10-12 09:31:01

标签: .net wpf design-patterns mvvm

我想控制下面的过程。我想通过订单保存客户。

enter image description here

1)写下客户的姓名,姓氏,电话 2)选择产品 3)按Insert

我可以用MVVM做到这一点!

但我不能:

如何在InsertCommand后显示消息框?以及如何激活wpf选项卡控件的第一个选项卡,也显示在网格中的客户订单中仅选择产品?

enter image description here

1 个答案:

答案 0 :(得分:2)

可以想到我已经做到的两种方式。

一种方法是在您的表单上设置一个包含您的消息的控件。通常,它的可见性是折叠的,但作为保存过程的一部分,您可以设置其可见性必须可见的属性。在您单击“确定”按钮之前,控件将变为可见,此时它将变为不可见。 对于小型解决方案,这是一种快速简便的方法,但如果您有更大的解决方案,那么您将更频繁地想要对话框 - 因此您需要更具可扩展性的解决方案 - 因此您可以在视图模型中注入对话框服务,或者使用消息来获取要显示的窗口的对话框控件。

因此,例如在我正在进行的项目中,我们正在使用mvvm灯,并且有一个带有子窗口的主窗口。主窗口注册对话框消息,当子窗口发布该消息时,它显示对话框。所以例如:

            public MainPage()
    {
        this.InitializeComponent();

        // http://mvvmlight.codeplex.com/discussions/209338?ProjectName=mvvmlight
        Messenger.Default.Register<DialogMessage>(this, OnDialogMessage);

    }


private static void OnDialogMessage(DialogMessage message)
{
    MessageBoxResult result = MessageBox.Show(message.Content, message.Caption, message.Button);
    message.ProcessCallback(result);
}

在要显示消息的表单中,您可以发布DialogMessage,并且已显示该消息的窗口将显示该消息。我们目前正在使用ServiceLocator来处理查找我们的消息框服务,尽管根据您的项目,最好注入它。

ServiceLocator.Current.GetInstance<IMessageBoxDisplayer>().Show(
                        "Selected Product has been saved", "Product Saved", false);

然后,您的messageBoxDisplayer将通过发布消息显示消息框:

    public Task<bool> Show(string messageBoxText, string caption, bool displayCancelButton)
    {
        if (caption == null)
        {
            throw new ArgumentNullException("caption");
        }

        var tcs = new TaskCompletionSource<bool>();

        var message = new DialogMessage(messageBoxText, mbr => tcs.SetResult(mbr == MessageBoxResult.OK))
            {
                Button = displayCancelButton ? MessageBoxButton.OKCancel : MessageBoxButton.OK,
                Caption = caption,
            };
        Messenger.Default.Send(message);

        return tcs.Task;
    }

显然,实现消息传递服务,服务定位器等需要的代码比此更多,但是这应该为您提供了一些可能的方法。如果您已经在使用框架,那么如果不值得研究的话,您可能会有很多这样的事情。

查看有关mvvmlight dialogmessage和dialogboxes的讨论: http://mvvmlight.codeplex.com/discussions/209338?ProjectName=mvvmlight

编辑: 刚刚注意到问题的第二部分。 要激活第二个选项卡,取决于您是如何创建它的。 TabControl本质上是一个项控件,因此您可以将其项源绑定到viewmodel集合,然后将SelectedItem绑定到Windows viewmodel上的ActiveTabViewModel属性(Mode = TwoWay),然后您可以将ActiveTabViewModel设置为您想要的那个它应该改变。或者我想你可能绑定SelectedIndex(虽然我还没有尝试过这种方式),例如:

<TabControl SelectedIndex="{Binding SelectedTabIndex, Mode=TwoWay}"/>

并且在视图模型上具有以下属性:     public int SelectedTabIndex         {             得到             {                 return _selectedTabIndex;             }

        set
        {
            this._selectedTabIndex = value;
            this.RaisePropertyChanged(() => this.SelectedTabIndex);
        }
    }

假设您有一个处理NotifyPropertyChanged的RaisePropertyChanged事件 - 如果您使用的是mvvmlight,那么它应该在那里。

然后在你的保存方法中设置SelectedTabIndex = x,它应该有希望改变到正确的标签。