绑定方法到WPF中的按钮

时间:2014-10-28 12:37:01

标签: c# wpf

我有这个控制台应用程序,我现在想要在WPF应用程序中。我是WPF的新手,所以我不确定从哪里开始。我目前有以下功能来启动服务器:

 public static void StartListening(string[] prefixes)
    {
        HttpListener listener = new HttpListener();

        if (prefixes == null || prefixes.Length == 0)
            throw new ArgumentException("prefixes");

        foreach (string s in prefixes)
        {
            listener.Prefixes.Add("http://" + s + "/");
        }
        listener.Start();
        Console.WriteLine("\nListening...");

        listener.BeginGetContext(new AsyncCallback(OnRequest), listener);
    }

现在我希望能够通过单击按钮在WPF中执行此操作。我已经在MainWindow.xaml.cs中有以下内容,但我可以使用一些提示如何将StartServerButton_Click绑定到我的StartListening()方法。我一直在寻找使用ICommand,但这对于这个相当简单的问题来说似乎是一个过于复杂的解决方案。

 public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        try
        {
            IPAddress[] addrs = Array.FindAll(Dns.GetHostEntry(string.Empty).AddressList,
               a => a.AddressFamily == AddressFamily.InterNetwork);
            ServerOutputTextBox.AppendText("Your IPv4 address is: ");
            foreach (IPAddress addr in addrs)
            {
                ServerOutputTextBox.AppendText(addr.ToString());
            }

            //Automatically set the IP address
            string[] ips = addrs.Select(ip => ip.ToString()).ToArray();
            Response.StartListening(ips);
        }
        catch (Exception e)
        {
            MessageBox.Show(e.Message);
        }

    }


    private void StartServerButton_Click(object sender, RoutedEventArgs e)
    {

    }

3 个答案:

答案 0 :(得分:3)

到目前为止,这两个答案都向您展示了如何使用代码隐藏点击事件来启动您的方法,但是由于您的标题要求{em>绑定 Button.Command属性到您的{{1}我想我会发一个关于如何做到这一点的答案。

您需要DataContext值才能绑定ICommand。此外,出于绑定目的,您通常需要所谓的Button.CommandRelayCommand,这只是一种说法的方式,它可以指向某个其他地方执行的无关代码。

如果您正在使用第三方框架(如Microsoft PRISM或MVVM Light),它们都已经专门为此设置了类,或者您可以创建自己的DelegateCommand版本以用于绑定。

这是我在不想使用第三方图书馆时经常使用的RelayCommand课程:

RelayCommand

然后,您的/// <summary> /// A command whose sole purpose is to relay its functionality to other /// objects by invoking delegates. The default return value for the /// CanExecute method is 'true'. /// </summary> public class RelayCommand : ICommand { readonly Action<object> _execute; readonly Predicate<object> _canExecute; /// <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; } #region ICommand Members [DebuggerStepThrough] public bool CanExecute(object parameters) { return _canExecute == null ? true : _canExecute(parameters); } public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } public void Execute(object parameters) { _execute(parameters); } #endregion // ICommand Members } 类将公开此RelayCommand的实例,该实例将转到您的方法以进行绑定,例如

DataContext

现在说,从你到目前为止给出的代码示例来看,你看起来并没有正确地利用WPF的绑定系统,所以这个解决方案可能不适合你和像其他人一样,使用OnClick方法可能更简单。

在理想的世界中,您的数据和业务逻辑都存在于与UI无关的类中,这些类用作UI组件后面的public ICommand StartServerCommand { get { // If command hasn't been created yet, create it if (_startServerCommand == null) { _startServerCommand = new RelayCommand( param => StartServer() ); } return _startServerCommand; } } private void StartServer() { var ips = GetIpAddresses(); Response.StartListening(ips); } ,并且您使用绑定从您的数据中提取数据用于在UI中显示的数据类。

如果您希望了解有关如何正确使用WPF的更多信息,我的博客上有一些初学者文章可能会对您有所帮助:

答案 1 :(得分:0)

从您的代码判断,加载窗口后,IP不会更改。因此,将ips设为私有并在按钮单击处理程序中使用它:

public partial class MainWindow : Window {
private string[] ips;

public MainWindow()
{
    InitializeComponent();

    try
    {
        IPAddress[] addrs = Array.FindAll(Dns.GetHostEntry(string.Empty).AddressList,
           a => a.AddressFamily == AddressFamily.InterNetwork);
        ServerOutputTextBox.AppendText("Your IPv4 address is: ");
        foreach (IPAddress addr in addrs)
        {
            ServerOutputTextBox.AppendText(addr.ToString());
        }

        //Automatically set the IP address
        ips = addrs.Select(ip => ip.ToString()).ToArray();

    }
    catch (Exception e)
    {
        MessageBox.Show(e.Message);
    }

}


private void StartServerButton_Click(object sender, RoutedEventArgs e)
{
     Response.StartListening(ips);
}

答案 2 :(得分:0)

我不确定我的问题是否正确。但这是你正在寻找的吗?

的Xaml:

<Button Click=StartServerButton_Click/>

代码背后:

private void StartServerButton_Click(object sender, RoutedEventArgs e)
{
    DoSomething();
}