【问题标题】:Rewrite "button.Click += ..." using ICommand in WPF在 WPF 中使用 ICommand 重写“button.Click += ...”
【发布时间】:2017-12-28 09:36:17
【问题描述】:

我正在使用外部 SDK。

namespace ProSimSDK 
{
    public class ArmedFailure
   {
     ...
     public static event ArmedFailureEventDelegate onNew;
     public void Reset();
     ...
   }
}

namespace ProSimSDK
{
   public delegate void ArmedFailureEventDelegate(ArmedFailure armedFailure);
}

当我尝试用 WPF 重写一些 Winform 代码时,我遇到了一些麻烦。在 Winform 中:

public Form1()
{
    InitializeComponent();
    ArmedFailure.onNew += new ArmedFailureEventDelegate(ArmedFailure_onNew);
}

// This function will be called when a new armedFailure is received
void ArmedFailure_onNew(ArmedFailure armedFailure)
{
      //Here is the code I need to rewrite in WPF.
      removeButton.Click += new EventHandler(delegate(object sender, EventArgs e)
        {
            failure.Reset();
        });
}

在 WPF 中,我使用列表框。通过一些指南,我正在使用 ListBox 模板和命令。 在 Window1.xaml 中:

<DataTemplate x:Key="ListBoxItemTemplate">
    <Grid>
        <TextBlock x:Name="TB" Margin="5,10,5,5" Grid.Column="2" Height="23" Text="{Binding}" VerticalAlignment="Top" />
        <Button HorizontalAlignment="Right" Grid.Column="3" Margin="500,10,5,0" CommandParameter="{Binding}" Command="{Binding ElementName=UC_Failures_Setting, Path=OnClickCommand}" Width="80" Click="Button_Click">remove</Button>
    </Grid>
</DataTemplate>

<ListBox x:Name="listbox" ItemTemplate="{StaticResource ListBoxItemTemplate}" Margin="0,661,982,0" SelectionChanged="ListBox_SelectionChanged">

Window1.xaml.cs

public Window1()
{
    InitializeComponent();

    //How to implement the same functionality of "removeButton.Click += new EventHandler(delegate(object sender, EventArgs e) {failure.Reset();});" shown in Winform???
    OnClickCommand = new ActionCommand(x => listbox.Items.Remove(x));
}

ActionCommand.cs:

 public class ActionCommand: ICommand
 {
    private readonly Action<object> Action;
    private readonly Predicate<object> Predicate;

    public ActionCommand(Action<object> action) : this(action, x => true)
    {

    }
    public ActionCommand(Action<object> action, Predicate<object> predicate)
    {
        Action = action;
        Predicate = predicate;
    }

    public bool CanExecute(object parameter)
    {
        return Predicate(parameter);
    }
    public void Execute(object parameter)
    {
        Action(parameter);
    }

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

我的列表框中的按钮如何实现与

相同的功能
removeButton.Click += new EventHandler(delegate(object sender, EventArgs e) 
{ failure.Reset(); });

在 Winform 中显示?在 WPF 中我不能这样写。谢谢。

【问题讨论】:

  • 在我看来,最简单的方法是准确了解绑定的工作原理并遵循 MVVM 的工作方式,然后通过视图的 XAML 将按钮的单击事件绑定到 ViewModel 上的方法。使用 WPF 时,MVVM 非常接近标准。
  • 当开始在 WPF 中学习 MVVM 时,最好的 2 个选择是 SimpleMVVMToolkit(My fav) 或 MVVMLight........使用棱镜
  • 我发现真正了解 WPF 对绑定所做的事情的最佳方法是尝试在我自己的库中重新实现这些库的一部分,并根据我的最佳猜测来处理它。然后查看真实图书馆的来源,看看我有多接近。速度不快,但信息量很大。直接使用 MVVM 库感觉就像我在学习库而不是学习 WPF 和 MVVM。当然,不要试图用生产级代码来做到这一点。使用“玩具”应用进行实验。
  • 感谢您的建议。我已经开始学习MVVM、绑定等了。

标签: c# wpf winforms icommand


【解决方案1】:

如果ListBox 填充有ArmedFailure 项目,那么命令接收的参数应该是ArmedFailure 项目。

OnClickCommand = new ActionCommand
( 
   x => 
   {
       var failure = (ArmedFailure)x;
       failure.Reset();
       listbox.Items.Remove(x);
   }
);

WinForms 中 Button.Click 处理程序中的所有内容都成为 wpf 中 ICommand.Execute 的一部分

【讨论】:

  • 非常感谢! ListBox 应填充 ArmedFailure 项。@ASh
猜你喜欢
  • 2017-06-10
  • 1970-01-01
  • 2010-10-13
  • 1970-01-01
  • 2020-04-27
  • 2015-07-12
  • 2014-05-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多