c# - WPF:如何使用 MVVM 将命令绑定(bind)到 ListBoxItem?

标签 c# wpf mvvm binding commandbinding

我刚刚开始学习 MVVM。我按照这个 MVVM tutorial 从头开始​​制作应用程序(我强烈推荐给所有 MVVM 初学者)。基本上,到目前为止我创建的是几个文本框,用户可以在其中添加他或她的数据,一个用于保存该数据的按钮随后将所有条目填充到 ListBox 中。

这就是我遇到的问题:我希望能够双击 ListBoxItem 并触发我创建并添加到我的 ViewModel 的命令。我不知道如何完成 XAML 端,即我不知道如何将该命令绑定(bind)到 ListBox(Item)。

这是 XAML:

...
<ListBox 
    Name="EntriesListBox" 
    Width="228" 
    Height="208" 
    Margin="138,12,0,0" 
    HorizontalAlignment="Left" 
    VerticalAlignment="Top" 
    ItemsSource="{Binding Entries}" />
...

这是 View 模型:

public class MainWindowViewModel : DependencyObject
{
    ...
    public IEntriesProvider Entries
    {
        get { return entries; }
    }

    private IEntriesProvider entries;
    public OpenEntryCommand OpenEntryCmd { get; set; }

    public MainWindowViewModel(IEntriesProvider source)
    {
        this.entries = source;
        ...
        this.OpenEntryCmd = new OpenEntryCommand(this);
    }
    ...
}

最后,这是我希望在用户双击 EntriesListBox 中的项目时执行的 OpenEntryCommand:

public class OpenEntryCommand : ICommand
{
    private MainWindowViewModel viewModel;

    public OpenEntryCommand(MainWindowViewModel viewModel)
    {
        this.viewModel = viewModel;
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public bool CanExecute(object parameter)
    {
        return parameter is Entry;
    }

    public void Execute(object parameter)
    {
        string messageFormat = "Subject: {0}\nStart: {1}\nEnd: {2}";
        Entry entry = parameter as Entry;
        string message = string.Format(messageFormat, 
                                       entry.Subject, 
                                       entry.StartDate.ToShortDateString(), 
                                       entry.EndDate.ToShortDateString());

        MessageBox.Show(message, "Appointment");
    }
}

请帮忙,我将不胜感激。

最佳答案

不幸的是,只有 ButtonBase 派生控件才有可能将 ICommand 对象绑定(bind)到它们的 Command 属性(对于 Click 事件)。

但是,您可以使用 Blend 提供的 API 将事件(如您的情况 ListBox 上的 MouseDoubleClick)映射到 ICommand 对象。

<ListBox>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="MouseDoubleClick">
            <i:InvokeCommandAction Command="{Binding YourCommand}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</ListBox>

您必须定义:xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 并引用 System.Windows。 Interactivity.dll.

-- 编辑-- 这是 WPF4 的一部分,但如果您不使用 WPF4,则可以使用 Microsoft.Windows.Interactivity。这个 dll 来自 Blend SDK,它不需要 Blend,来自这里: http://www.microsoft.com/downloads/en/details.aspx?FamilyID=f1ae9a30-4928-411d-970b-e682ab179e17&displaylang=en

更新:我找到了一些可以帮助您的东西。检查this link on MVVM Light Toolkit其中包含有关如何执行此操作的演练,以及 link到所需的图书馆。 MVVM Light Toolkit 是一个非常有趣的框架,用于将 MVVM 与 Silverlight、WPF 和 WP7 一起应用。

希望这有帮助:)

关于c# - WPF:如何使用 MVVM 将命令绑定(bind)到 ListBoxItem?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5545187/

相关文章:

c# - 将 DataGrid 列宽绑定(bind)到另一个 DataGrid 的两列

c# - 在对话框 View 模型的异步加载中捕获异常

wpf - 使用WPF M-V-VM模式显示弹出窗口的正确方法

c# - 如何旋转图像wpf

c# - 调用 WebServices 的通用方法

c# - 从 System.IO.Abstractions 中抛出 UnauthorizedAccessException

c# - ERP会计年度交易表的单数据库VS多数据库?

wpf - DataGrid 的列宽 (width = "*") 不是 "refreshed"

c# - MEF 导出中的 ExpandoObject

c# - Linq 表达式。帮助最小化代码