Bor*_*ris 26 c# wpf binding mvvm commandbinding
我刚开始学习MVVM.我通过遵循这个MVVM教程从头开始制作应用程序(我强烈推荐给所有MVVM初学者).基本上,我到目前为止创建的是一些文本框,其中用户添加他或她的数据,一个按钮来保存该数据,随后使用所有条目填充ListBox.
这就是我陷入困境的地方:我希望能够双击ListBoxItem并触发我创建并添加到ViewModel的命令.我不知道如何完成XAML方面,即我不知道如何将该命令绑定到ListBox(Item).
这是XAML:
...
<ListBox
Name="EntriesListBox"
Width="228"
Height="208"
Margin="138,12,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
ItemsSource="{Binding Entries}" />
...
Run Code Online (Sandbox Code Playgroud)
这是ViewModel:
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);
}
...
}
Run Code Online (Sandbox Code Playgroud)
最后,这是我想在用户双击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");
}
}
Run Code Online (Sandbox Code Playgroud)
请帮忙,我很感激.
Abd*_*men 65
不幸的是,只有ButtonBase派生控件才有可能将ICommand对象绑定到它们的Command属性(对于Click事件).
但是,您可以使用混合到(在你的情况一样映射的事件提供了一个API MouseDoubleClick的ListBox)一个ICommand对象.
<ListBox>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction Command="{Binding YourCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBox>
Run Code Online (Sandbox Code Playgroud)
你必须定义: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
更新:我找到了一些可以帮到你的东西.检查MVVM Light Toolkit上的这个链接,其中包含有关如何执行此操作的演练,以及指向所需库的链接.MVVM Light Toolkit是一个非常有趣的框架,用于将MVVM应用于Silverlight,WPF和WP7.
希望这可以帮助 :)
由于DoubleClick事件,这很棘手.有几种方法可以做到这一点:
2和3可能更纯粹,但坦率地说,1更容易,更简单,而不是世界上最糟糕的事情.对于一次性案例,我可能会使用方法#1.
现在,如果您更改了要求使用每个项目的超链接,那么这将更容易.首先命名XAML中的根元素 - 例如,对于一个Window:
<Window .... Name="This">
Run Code Online (Sandbox Code Playgroud)
现在,在ListBox项的DataTemplate中,使用以下内容:
<ListBox ...>
<ListBox.ItemTemplate>
<DataTemplate>
<Hyperlink
Command="{Binding ElementName=This, Path=DataContext.OpenEntryCmd}"
Text="{Binding Path=Name}"
/>
Run Code Online (Sandbox Code Playgroud)
ElementName绑定允许您从ViewModel的上下文中解析OpenEntryCmd,而不是特定的数据项.
编辑:我作为一个没有经验的 WPF 开发人员写了这篇文章,现在我要么使用提供事件到命令绑定的框架,要么简单地使用按钮并重新设计它的样式。当然,为了获得最大的灵活性,这可能更好。
我发现最好的方法是为我的内容创建一个简单的用户控件包装器,并使用命令和参数的依赖属性。
我这样做的原因是因为按钮没有将单击事件冒泡到我的列表框,这阻止了它选择列表框项。
CommandControl.xaml.cs:
public partial class CommandControl : UserControl
{
public CommandControl()
{
MouseLeftButtonDown += OnMouseLeftButtonDown;
InitializeComponent();
}
private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs mouseButtonEventArgs)
{
if (Command != null)
{
if (Command.CanExecute(CommandParameter))
{
Command.Execute(CommandParameter);
}
}
}
public static readonly DependencyProperty CommandProperty =
DependencyProperty.Register("Command", typeof(ICommand),
typeof(CommandControl),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.None));
public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
public static readonly DependencyProperty CommandParameterProperty =
DependencyProperty.Register("CommandParameter", typeof(object),
typeof(CommandControl),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.None));
public object CommandParameter
{
get { return (object)GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
}
}
Run Code Online (Sandbox Code Playgroud)
命令控制.xaml:
<UserControl x:Class="WpfApp.UserControls.CommandControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Background="Transparent">
</UserControl>
Run Code Online (Sandbox Code Playgroud)
用法:
<ListBoxItem>
<uc:CommandControl Command="{Binding LoadPageCommand}"
CommandParameter="{Binding HomePageViewModel}">
<TextBlock Text="Home" Margin="0,0,0,5" VerticalAlignment="Center"
Foreground="White" FontSize="24" />
</uc:CommandControl>
</ListBoxItem>
Run Code Online (Sandbox Code Playgroud)
内容可以是任何内容,当单击该控件时,它将执行该命令。
编辑:添加Background="Transparent"到 UserControl 以在控件的整个区域上启用单击事件。