【问题标题】:MVVM View Event to ViewModelMVVM 视图事件到 ViewModel
【发布时间】:2016-06-06 14:03:32
【问题描述】:

我正在 WPF 中构建我的第一个 MVVM 应用程序。在这一刻,我试图通过双击列表框中的项目来引发事件。该事件由 View 处理,如下代码所示。

现在我想向 ViewModel 发送列表框中被双击的项目的索引。我该怎么做?

PS:ClassObject 和 ClassDiagram 都是自定义类,它们都有相同的属性“Name”

查看

public partial class ProjectView : UserControl
    {
        public ProjectView()
        {
            InitializeComponent();
            this.DataContext = new ProjectViewModel();
        }

        public void listBoxProject_MouseDoubleClick(object sender,MouseButtonEventArgs e)
        {
            MessageBox.Show(listBoxProject.SelectedIndex.ToString()); //Send index to ViewModel
        }
    }

XAML

<ListBox x:Name="listBoxProject" ItemsSource="{Binding CollectionList}" HorizontalAlignment="Stretch" Margin="-1,32,-1,-1" VerticalAlignment="Stretch" Width="auto" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
            DisplayMemberPath="Name"
            SelectedValuePath="Name"
            >
    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource {x:Type ListBoxItem}}">
            <EventSetter Event="MouseDoubleClick" Handler="listBoxProject_MouseDoubleClick"/>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

视图模型

namespace VITUMLEditor.ViewModels
{
    public class ProjectViewModel:BaseViewModel
    {
        private readonly CompositeCollection collectionList = new CompositeCollection();

        public ICommand AddClassCommand
        {
            get { return new DelegateCommand(AddClass); }
        }

        public ICommand AddClassDiagramCommand
        {
            get { return new DelegateCommand(AddClassDiagram); }
        }

        private void AddClass()
        {
            collectionList.Add(new ClassObject("Class" + ClassObject.Key, VisibilityEnum.Public));
        }

        private void AddClassDiagram()
        {
            collectionList.Add(new ClassDiagram("ClassDiagram" + ClassDiagram.Key));
        }

        public CompositeCollection CollectionList
        {
            get { return collectionList; }
        }
    }
}

【问题讨论】:

标签: c# wpf mvvm listbox


【解决方案1】:

原则上,您应该使用命令来执行此操作。但是你必须编写代码来使双击调用命令。以下内容很简单,对于大量常见情况来说已经足够好了。我们在生产代码中有几十个这样的代码,它们不会给我们带来任何痛苦,因为所讨论的视图-视图模型关系都是 1:1 的,并且将保持如此。请记住,它是不纯的 MVVM,并且可以任意限制您的选择。

向视图模型添加一个适当命名和参数化的方法:

public void ActivateItem(object item)
{
    //  Better if these two classes share a common base class or interface with 
    //  a virtual function to be called in this case, but there I go ranting from 
    //  the pulpit again. 
    if (item is ClassObject)
    {
        //  Stuff
    }
    else if (item is ClassDiagram)
    {
        //  Other stuff
    }
}

并从视图中调用它:

//  This is faintly sketchy, in many people's view, because in principle 
//  a view can have any type of viewmodel that has properties of the 
//  appropriate names and types. You *could* make many viewmodels all 
//  implement some interface that supports common stuff, and make this that
//  type. That wouldn't save you from the MVVM Inquisition, but it would be
//  more flexible than this. 
protected ProjectViewModel ViewModel { get { return DataContext as ProjectViewModel; } }

public void listBoxProject_MouseDoubleClick(object sender,MouseButtonEventArgs e)
{
    //  WARNING you need to add range checking here
    var lb = sender as ListBox;
    var item = lb.Items[lb.SelectedIndex];

    ViewModel.ActivateItem(item);
}

【讨论】:

  • 谢谢!我将事件中的代码编辑为 ViewModel.OpenClassDiagram(listBoxProject.SelectedItem); 成功了
猜你喜欢
  • 1970-01-01
  • 2011-01-31
  • 2011-11-04
  • 1970-01-01
  • 2023-03-27
  • 2019-12-24
  • 2011-07-03
  • 2010-11-27
  • 2010-12-01
相关资源
最近更新 更多