c# - WPF 按钮动态命令

标签 c# wpf

我有一个 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的CanExecuteChanged事件所以你不能顺利编译;此外,此 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();
    });

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

相关文章:

c# - 如何根据键值对创建对象

c# - 如何让WPF UI 的滑动动画更加有形?

c# - 在使用 ItemsSource 和帮助使用 Combo Box 之前,WPF Items 集合必须为空

c# - 通用约束语法和用法

c# - 将一个函数指向另一个函数

c# - linq Expression<TDelegate> 赋值如何在语言语法级别上工作

c# - 将 WPF DataGrid 直接绑定(bind)到 EntityCollection<T>

WPF:如何在 XAML-DataGrid 中使用 DatePicker

wpf - 如何禁用某些按钮的加速键

c# - 使用列表集中管理类型映射?