Подтвердить что ты не робот

Как связать команду Close с кнопкой

Самый простой способ - реализовать обработчик событий ButtonClick и вызвать метод Window.Close(), но как это сделать с помощью привязки Command?

4b9b3361

Ответ 1

Я думаю, что в сценариях реального мира простой обработчик кликов, вероятно, лучше, чем чрезмерно сложные командные системы, но вы можете сделать что-то вроде этого:

используя RelayCommand из этой статьи http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

public class MyCommands
{
    public static readonly ICommand CloseCommand =
        new RelayCommand( o => ((Window)o).Close() );
}

<Button Content="Close Window"
        Command="{X:Static local:MyCommands.CloseCommand}"
        CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/>

Ответ 2

Все, что требуется, это немного XAML...

<Window x:Class="WCSamples.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Window.CommandBindings>
        <CommandBinding Command="ApplicationCommands.Close"
                        Executed="CloseCommandHandler"/>
    </Window.CommandBindings>
    <StackPanel Name="MainStackPanel">
        <Button Command="ApplicationCommands.Close" 
                Content="Close Window" />
    </StackPanel>
</Window>

И немного С#...

private void CloseCommandHandler(object sender, ExecutedRoutedEventArgs e)
{
    this.Close();
}

(адаптирован из этой статьи MSDN)

Ответ 3

Собственно, это возможно без кода С#. Ключ должен использовать взаимодействия:

<Button Content="Close">
  <i:Interaction.Triggers>
    <i:EventTrigger EventName="Click">
      <ei:CallMethodAction TargetObject="{Binding ElementName=window}" MethodName="Close"/>
    </i:EventTrigger>
  </i:Interaction.Triggers>
</Button>

Чтобы это сработало, просто установите x:Name вашего окна в "окно" и добавьте эти два пространства имен:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"

Это требует, чтобы вы добавляли DLL Expression Blend SDK в свой проект, в частности Microsoft.Expression.Interactions.

Если у вас нет Blend, SDK можно скачать здесь.

Ответ 4

Самое простое решение, о котором я знаю, - установить свойство IsCancel в true для закрытия Button:

<Button Content="Close" IsCancel="True" />

Никаких привязок не требуется, WPF сделает это автоматически!

Ссылка: Свойство MSDN Button.IsCancel.

Ответ 5

Для .NET 4.5 SystemCommands класс будет делать трюк (пользователи .NET 4.0 могут использовать расширение оболочки WPF google - Microsoft.Windows.Shell или Nicholas Solution).

    <Window.CommandBindings>
        <CommandBinding Command="{x:Static SystemCommands.CloseWindowCommand}" 
                        CanExecute="CloseWindow_CanExec" 
                        Executed="CloseWindow_Exec" />
    </Window.CommandBindings>
    <!-- Binding Close Command to the button control -->
    <Button ToolTip="Close Window" Content="Close" Command="{x:Static SystemCommands.RestoreWindowCommand}"/>

В Code Behind вы можете реализовать обработчики следующим образом:

    private void CloseWindow_CanExec(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = true;
    }

    private void CloseWindow_Exec(object sender, ExecutedRoutedEventArgs e)
    {
        SystemCommands.CloseWindow(this);
    }

Ответ 6

В начале мне также было немного сложно понять, как это работает, поэтому я хотел опубликовать лучшее объяснение того, что на самом деле происходит.

Согласно моим исследованиям, лучший способ справиться с такими вещами - использовать Command Bindings. То, что происходит, - это "Сообщение", передается всем в программе. Итак, вам нужно использовать CommandBinding. По сути, это говорит: "Когда вы слышите это сообщение, сделайте это".

Итак, в вопросе пользователь пытается закрыть окно. Первое, что нам нужно сделать, это настроить наши функции, которые будут вызываться при трансляции SystemCommand.CloseWindowCommand. При желании вы можете назначить функцию, которая определяет, должна ли выполняться команда. Примером может быть закрытие формы и проверка того, сохранил ли Пользователь.

MainWindow.xaml.cs(или другой код)

void CloseApp( object target, ExecutedRoutedEventArgs e ) {
    /*** Code to check for State before Closing ***/
    this.Close();
}

void CloseAppCanExecute( object sender, CanExecuteRoutedEventArgs e ) {
    /*** Logic to Determine if it is safe to Close the Window ***/
    e.CanExecute = true;
}

Теперь нам нужно настроить "Соединение" между SystemCommands.CloseWindowCommand и CloseApp и CloseAppCanExecute

MainWindow.xaml(или все, что реализует CommandBindings)

<Window.CommandBindings>
    <CommandBinding Command="SystemCommands.CloseWindowCommand"
                    Executed="CloseApp"
                    CanExecute="CloseAppCanExecute"/>
</Window.CommandBindings>

Вы можете опустить CanExecute, если знаете, что команда должна быть всегда выполнена. Сохранить может быть хорошим примером в зависимости от приложения. Вот пример:

<Window.CommandBindings>
    <CommandBinding Command="SystemCommands.CloseWindowCommand"
                    Executed="CloseApp"/>
</Window.CommandBindings>

Наконец, вы должны сообщить UIElement отправить команду CloseWindowCommand.

<Button Command="SystemCommands.CloseWindowCommand">

На самом деле это очень простая вещь, просто установите связь между Command и фактической функцией Execute, затем сообщите Control, чтобы отправить команду в остальную часть вашей программы, говоря: "Хорошо, все выполняют ваши функции для команды CloseWindowCommand".

На самом деле это очень хороший способ передать это, потому что вы можете полностью использовать исполняемую функцию, не имея такой оболочки, как вы, например, с помощью WinForms (с помощью ClickEvent и вызова функции в функции события), например:

protected override void OnClick(EventArgs e){
    /*** Function to Execute ***/
}

В WPF вы присоединяете функцию к команде и сообщаете UIElement выполнить функцию, прикрепленную к команде.

Надеюсь, это прояснит ситуацию...