我的WPF表单设置如下;
<ListBox x:Name="lbModules" HorizontalAlignment="Stretch" Margin="0,0,0,0" VerticalAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<Button Command="{Binding OnClick}">
<StackPanel>
<Image Source="{Binding ModuleIcon}"/>
<Label Content="{Binding ModuleName}"/>
</StackPanel>
</Button>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel></WrapPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
在后面的代码中,lbModules
被赋予List<ModuleButton>
作为ItemsSource,其中ModuleButton
定义如下;
internal class ModuleButton
{
public ImageSource ModuleIcon {get; set;}
public string ModuleName {get; set;}
public ICommand OnClick {get; set;}
}
我的问题是以动态方式定义OnClick命令。我需要这样做,因为我正在使用MEF,而OnClick事件在技术上是在不同的程序集中。我只需要致电module.GetForm()
,但似乎并不那么简单......
我按如下方式构建ModuleButton;
Lazy<IModule, IModuleMetadata> moduleCopy = module;
ModuleButton button = new ModuleButton
{
ModuleName = moduleCopy.Metadata.ModuleName,
ModuleIcon =
Imaging.CreateBitmapSourceFromHBitmap(moduleCopy.Value.ModuleButtonIcon.GetHbitmap(),
IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()),
OnClick = // TODO: Somehow call moduleCopy.Value.GetForm()
};
我一直在广泛搜索,在Google查看各种结果,this是我最新的来源之一。
我可以做我想做的事吗?如果是这样,怎么样?
答案 0 :(得分:3)
好的,试试我的版本,因为Patrick的答案没有实现ICommand's CanExecuteChanged event
,所以你不能顺利编译;此外,这个RelayCommand
已经超载,只需要一个参数 - CanExecute
始终返回true - 使其更易于使用。
摘自MSDN杂志文章WPF Apps With The Model-View-ViewModel Design Pattern。
public class RelayCommand : ICommand
{
#region Fields
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
#endregion // Fields
#region Constructors
/// <summary>
/// Creates a new command that can always execute.
/// </summary>
/// <param name="execute">The execution logic.</param>
public RelayCommand(Action<object> execute)
: this(execute, null)
{
}
/// <summary>
/// Creates a new command.
/// </summary>
/// <param name="execute">The execution logic.</param>
/// <param name="canExecute">The execution status logic.</param>
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
#endregion // Constructors
#region ICommand Members
[DebuggerStepThrough]
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
_execute(parameter);
}
#endregion // ICommand Members
}
和
OnClick = new RelayCommand ((o) =>
{
moduleCopy.Value.GetForm();
});