none
как обработать клик на кнопке в WpF RRS feed

  • Вопрос

  • Добрый день. Недавно начал изучать WPF и столкнулся с одной проблемой. Создаю стиль окна, в котором содержится вся балалайка касаемая заголовка окна и кнопки закрыть. Но вот как обработать клик этой самой кнопки не могу понять.

      <Style TargetType="Window" x:Key="WindowStyle">
        <Setter Property="WindowStyle" Value="None" />
        <Setter Property="ResizeMode" Value="NoResize" />
        <Setter Property="Template">
          <Setter.Value>
            <ControlTemplate TargetType="{x:Type Window}">
              <Border BorderThickness="1" Background="{DynamicResource BackBrush}" BorderBrush="{DynamicResource BorderBrush}">
                
                <!--Grid всего окна-->
                <Grid>             
                  
                  <Grid.RowDefinitions>
                    <RowDefinition Height="25" />
                    <RowDefinition />
                  </Grid.RowDefinitions>
                  
                  <Grid Background="{DynamicResource TopGradient}">
                    <Grid.ColumnDefinitions>
                      <ColumnDefinition Width="50" />
                      <ColumnDefinition />
                      <ColumnDefinition Width="50" />
                    </Grid.ColumnDefinitions>
    
                    <!--Заголовок окна во второй ячейке-->
                    <Label 
                      Content="{TemplateBinding Title}" 
                      Style="{DynamicResource WindowTitle}" 
                      Grid.Column="1"/>
    
                    <!--Close Button в третьей ячейке-->
                    <Button
                      x:Name="CloseButton"
                      BorderThickness="3"
                      Content="{DynamicResource CloseButtonPath}"
                      Background="{DynamicResource CloseButtonBackgroundBrush}"
                      Style="{DynamicResource CloseButton}"
                      Grid.Column="2"
                      Padding="3"
                      Margin="3" />
                  </Grid>
                  
                </Grid>
                
              </Border>
            </ControlTemplate>
          </Setter.Value>
        </Setter>
      </Style>

    Собственно это сам стиль. Он кстати хранится в ресурсах.

    А вот ко, которым пробовал что-то сделать. Но понял что так нельзя, ибо у кнопки нету атрибута x:Key, а как обратится к ней по имени не понимаю.

    Ну и вопрос как дальше быть?

    ResourceDictionary styleDictionary = new ResourceDictionary();
    
        public MainWindow()
        {
          InitializeComponent();
    
          try
          {
            styleDictionary.Source = new Uri("/StyleDictionary.xaml", UriKind.Relative);
            
            Button closeButton = styleDictionary["CloseButton"] as Button;
            closeButton.Click += new RoutedEventHandler(closeButton_Click);
          }
          catch (Exception e)
          {
            MessageBox.Show(e.Message);
          }
        }
    
        void closeButton_Click(object sender, RoutedEventArgs e)
        {
          Close(); 
        }
    

    5 марта 2011 г. 3:24

Ответы

  • Можно воспользоваться вариантом, предложенным здесь - Handling events from within a ControlTemplate in WPF и переопределять метод OnApplyTemplate() для каждого окна:

      public override void OnApplyTemplate()
      {
       DependencyObject d = GetTemplateChild("CloseButton");
       if (d != null)
       {
        (d as Button).Click += new RoutedEventHandler(MainWindow_Click);
       }
    
       base.OnApplyTemplate();
      }
    
      void MainWindow_Click(object sender, RoutedEventArgs e)
      {
       Close();
      }
    

     

    Но помоему это плохой вариант. Лучше воспользоваться командами:

    1) добавить в ваш шаблон, в определение кнопки Command="ApplicationCommands.Close"

    2) определить у окна привязку комманды:

     <Window.CommandBindings>
      <CommandBinding Command="ApplicationCommands.Close"
          Executed="CloseCommandHandler"/>
     </Window.CommandBindings>
    

    3) Определить сам метод CloseCommandHandler:
      private void CloseCommandHandler(object sender, ExecutedRoutedEventArgs e)
      {
       Close();
      }
    

     


    Для связи [mail]

    • Предложено в качестве ответа Abolmasov Dmitry 24 марта 2011 г. 8:53
    • Помечено в качестве ответа I.Vorontsov 29 марта 2011 г. 8:10
    13 марта 2011 г. 8:42

Все ответы

  • Вот пример того как это делается =)

    Имеем форму с кнопкой:

    <Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
      <Grid>
        <Button Content="Button" Height="40" HorizontalAlignment="Left" Margin="50,50,0,0" Name="button1" VerticalAlignment="Top" Width="147" Click="button1_Click" />
      </Grid>
    </Window>
    

    Имеем файл с кодом C#:

    using System.Windows;
     
    namespace WpfApplication2
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
     
            private void button1_Click(object sender, RoutedEventArgs e)
            {
                MessageBox.Show("Меня нажали =)");
            }
        }
    }
    


    E-mail: Svatoslav.Pankratov@gmail.com Blog: svyatoslavpankratov.blogspot.com
    5 марта 2011 г. 8:26
  • Видимо неправильно объяснил проблему. Мне надо обработать клик по кнопке которая описывается только в ресурсах, в шаблоне формы. Причем ресурс отдельным файлом лежит. Суть в общем в следующем - хочу создать шаблон окна, естественно на окне должна быть кнопка закрыть. В последствии хочу использовать шаблон для создания приложения многооконного, но с одинаковым стилем.

    PS. И кстати заинтересовал вопрос: стоит ли в App.xaml.cs писать какие-либо свои методы? Или все-таки не рекомендуется?

    7 марта 2011 г. 15:22
  • PS. И кстати заинтересовал вопрос: стоит ли в App.xaml.cs писать какие-либо свои методы? Или все-таки не рекомендуется?

    Туда хорошо вписываются методы по инициализации всего приложения.
    Blog: svyatoslavpankratov.blogspot.com
    12 марта 2011 г. 13:10
  • Можно воспользоваться вариантом, предложенным здесь - Handling events from within a ControlTemplate in WPF и переопределять метод OnApplyTemplate() для каждого окна:

      public override void OnApplyTemplate()
      {
       DependencyObject d = GetTemplateChild("CloseButton");
       if (d != null)
       {
        (d as Button).Click += new RoutedEventHandler(MainWindow_Click);
       }
    
       base.OnApplyTemplate();
      }
    
      void MainWindow_Click(object sender, RoutedEventArgs e)
      {
       Close();
      }
    

     

    Но помоему это плохой вариант. Лучше воспользоваться командами:

    1) добавить в ваш шаблон, в определение кнопки Command="ApplicationCommands.Close"

    2) определить у окна привязку комманды:

     <Window.CommandBindings>
      <CommandBinding Command="ApplicationCommands.Close"
          Executed="CloseCommandHandler"/>
     </Window.CommandBindings>
    

    3) Определить сам метод CloseCommandHandler:
      private void CloseCommandHandler(object sender, ExecutedRoutedEventArgs e)
      {
       Close();
      }
    

     


    Для связи [mail]

    • Предложено в качестве ответа Abolmasov Dmitry 24 марта 2011 г. 8:53
    • Помечено в качестве ответа I.Vorontsov 29 марта 2011 г. 8:10
    13 марта 2011 г. 8:42