Есть несколько сложностей в том, что вы делаете здесь, которые не сразу очевидны. Одним из них является то, что вы не можете просто определить какой-либо обработчик, и он будет работать. Вы также должны подписаться на это событие. Это делегат, которого вы как бы подключаете к событию.
Как электрический прибор, вам нужно подключить его, прежде чем что-либо произойдет.
Вот некоторая разметка и код для изучения что происходит.
Чтобы я мог видеть сообщения, я буду использовать список, в который я буду добавлять элементы. Они будут отображаться в виде списка сообщений.
Title="MainWindow" Height="450" Width="800"
Button.Click="Window_Button_Click">
<Grid Name="agrid">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ListBox Name="lb"
Grid.Column="1"/>
</Grid>
Я подключаю обработчик нажатия кнопки на уровне окна. Это будет обрабатывать события щелчка, которые всплывают на него из любой точки окна. Читайте о барботировании и туннелировании маршрутизируемых событий, если это новая концепция для вас.
https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/routed-events-overview
Затем я собираюсь динамически добавить кнопку. По умолчанию это будет столбец 0 сетки и появится слева.
Как вы увидите, если вы попробуете это.
Я также подписываюсь еще на два события кнопки.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Button newBtn = new Button();
newBtn.Content = "Test";
newBtn.Name = "btnTest";
agrid.Children.Add(newBtn);
newBtn.MouseUp += NewBtn_MouseUp;
newBtn.PreviewMouseDown += NewBtn_PreviewMouseDown;
}
private void NewBtn_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
Button btn = sender as Button;
string theName = btn?.Name ?? "Something was Preview Mouse Downed but I don't know what";
lb.Items.Add($"Button PREVIEW MouseUp {theName}");
}
private void NewBtn_MouseUp(object sender, MouseButtonEventArgs e)
{
Button btn = sender as Button;
string theName = btn?.Name ?? "Something was Mouse Upped but I don't know what";
lb.Items.Add($"Button MouseUp {theName}");
}
private void Window_Button_Click(object sender, RoutedEventArgs e)
{
Button btn = e.OriginalSource as Button;
string theName = btn?.Name ?? "Something was CLICKED in the window but I don't know what";
lb.Items.Add($"Window Button Click {theName}");
}
}
Приведенный выше код довольно быстрый и грязный.
Обратите внимание, что обработчик всплывающих событий интересуется источником источника события, так как он передан по дереву, и отправитель не будет кнопкой.
f5, чтобы раскрутить ее и нажать кнопку.
Там вас ждет сюрприз.
Нет сообщения от mouseup.
Это потому что кнопка предназначена для нажатия, а не mousedown и мыши. Код в ButtonBase работает с некоторыми событиями мыши, и, поскольку он обрабатывает их, ваш обработчик не будет запускаться.
Так что, мы надеемся, кое-что объяснено в событиях.
Есть Однако следует упомянуть несколько вещей.
Почти все разработки wpf используют MVVM и привязывают команду к свойству команды кнопки, а не используют события вообще.
Добавление динамич c содержимое также обычно не выполняется в коде, подобном этому.
Существует ряд опций, которые включают шаблоны данных. Это очень часто встречается в подходе под названием viewmodel.
Вы также можете создать пользовательский интерфейс, переведя xaml в виде строки в элементы управления. Это рекомендуемый способ создания пользовательского интерфейса, который должен быть динамическим c, когда вы не можете использовать стили или шаблоны. Вам, наверное, еще рано вникать в эти вещи, но к вашему сведению https://social.technet.microsoft.com/wiki/contents/articles/28797.wpf-dynamic-xaml.aspx