我有一个如下设置的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是我的最新消息之一。

有可能做我想做的事吗?如果是这样,怎么办?

最佳答案

好的,尝试我的版本,因为Patrick的答案没有实现ICommand's CanExecuteChanged event,所以您不能顺利编译。此外,此RelayCommand具有仅包含一个参数的'ctor重载-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();
    });

关于c# - WPF按钮动态命令,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27096514/

10-17 01:57