2014-10-28 4 views
0

У меня есть консольное приложение, которое я теперь хочу сделать в приложении 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) 
    { 

    } 
+0

Не так много WPFish. У вас может быть модель (ваш сервер или лучше его _view_) и команды для взаимодействия с ней ... –

ответ

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); 
} 
0

Я не совсем уверен, правильно ли я получил ваш вопрос. Но это то, что вы ищете?

Xaml:

<Button Click=StartServerButton_Click/> 

Код позади:

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

Правильно. У меня уже есть кнопка

+0

О, все в порядке. Тогда я предлагаю вам проверить ответ Рэйчел, потому что это похоже на звездный пример того, как это сделать правильно. – Mathew

3

Оба ответа до сих пор показывают, как использовать код фоновым нажмите событие, чтобы начать свой метод, однако, так как ваш заголовок спрашивает о связываяButton.Command собственности на ваш DataContext, я решил, что я опубликую ответ о том, как это сделать.

Для того, чтобы связать Button.Command, необходимо значение ICommand. Кроме того, для целей привязки обычно требуется то, что называется RelayCommand или DelegateCommand, что является просто причудливым способом сказать команду, которая может указывать на какой-то несвязанный код в другом месте для выполнения.

Если вы используете стороннюю инфраструктуру, такую ​​как Microsoft PRISM или MVVM Light, у них обоих есть класс специально для этого уже, или вы можете создать свою собственную версию RelayCommand для использования со связями.

Вот класс для RelayCommand, что я обычно использую, когда я не хочу использовать 3-библиотеки:

/// <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 
} 

Вашего DataContext класс затем подвергнуть экземпляр этого RelayCommand, который идет к вашему способу связывания целей, как этот

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); 
} 

Теперь, когда сказал, из примера кода вы дали до сих пор вы не смотрите, как вы принимаете преимущество системы обязательного WPF в правильно, так что это решение не может быть для вас и я t может быть проще просто использовать метод OnClick, как показали другие.

В идеальном мире ваши данные и бизнес-логика будут существовать в классах, не связанных с пользовательским интерфейсом, которые используются в качестве DataContext за компонентами пользовательского интерфейса, и вы будете использовать привязки для извлечения данных из своего класса данных для отображения в пользовательский интерфейс.

Если вы хотите узнать больше о том, как использовать WPF правильно, у меня есть некоторые начинающие статьи на моем блоге, которые могут помочь вам:

Смежные вопросы