Динамически добавлена кнопка WPF: события не запускаются

1

Я выполнил базовый пользовательский контроль WPF для всех своих пользовательских элементов для наследования. В этом базовом классе usercontrol я хочу иметь кнопку, связанную с событием клика. Я сделал это так:

public class MBaseUserControl : UserControl
{
  //[...]
    protected override void OnContentChanged(object oldContent, object newContent)
    {
        base.OnContentChanged(oldContent, newContent);

        StackPanel mainPanel = new StackPanel();
        EditButton = new Button();
        EditButton.Height = EditButton.Width = 24;
        EditButton.MouseEnter += EditButton_MouseEnter;
        EditButton.MouseLeave += EditButton_MouseLeave;
        EditButton.Click += new RoutedEventHandler(EditButton_Click);
        EditButton.Background = Brushes.Transparent;
        EditButton.BorderBrush = Brushes.Transparent;
        EditButton.HorizontalAlignment = System.Windows.HorizontalAlignment.Right;
        EditButton.VerticalAlignment = System.Windows.VerticalAlignment.Top;

        StackPanel buttonPanel = new StackPanel();
        Image editButtonImage =     ImageTools.ConvertDrawingImageToWPFImage(Properties.Resources.edit, 24, 24);
        buttonPanel.Children.Add(editButtonImage);

        EditButton.Content = buttonPanel;

        mainPanel.Children.Add(EditButton);
        //Add this to new control
        ((IAddChild)newContent).AddChild(mainPanel);
        SetCMSMode(false);
    }
}

Но когда я нажимаю кнопку на графическом интерфейсе, ничего не запускается (ни события мыши, ни события клика). Что я упустил?

Спасибо заранее!

  • 0
    Я бы предпочел изменить базовый UserControl, чтобы иметь «статические» элементы управления, такие как ваша кнопка редактирования в стиле по умолчанию, чтобы вы могли связать их с командами, определенными в базе, и не беспокоиться о перехвате обработчиков событий при изменении содержимого. Вы можете добавить ContentControl к вашему стилю по умолчанию и связать его с DependencyProperty на базе.
  • 0
    Кажется, мои навыки WPF недостаточно велики, чтобы понять, что вы будете делать. У вас есть пример этого?
Показать ещё 1 комментарий
Теги:
wpf
dynamic
user-controls

2 ответа

1
Лучший ответ

Вы можете попробовать шаблон UserControl чтобы его Content отображалось внутри какого-либо другого контента. Заметьте, он не тестировался, но я думаю, что он должен работать.

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:l="clr-namespace:DemoUni">
    <ControlTemplate x:Key="SomeKey" TargetType="UserControl">
        <Grid x:Name="PART_Grid">
            <ContentPresenter x:Name="PART_Content" Content="{Binding}"/>
            <!-- ... some other content -->
        </Grid>
    </ControlTemplate>
</ResourceDictionary>

В конструкторе UserControl

var dictionary = new ResourceDictionary();
// xaml containing control template
dictionary.Source = new Uri("/ProjectName;component/MyUserControlTemplate.xaml", UriKind.Relative);
Template = dictionary["SomeKey"] as ControlTemplate;

Чтобы получить доступ к другому контенту (например, Grid)

    private Grid _partGrid;
    private Grid PartGrid
    {
        get
        {
            if (_partGrid == null)
                _partGrid = (Grid)Template.FindName("PART_Grid", this);
            return _partGrid;
        }
    }

Небольшой недостаток - это то, что вы не можете получить доступ к PARTs в конструкторе, так что вам нужно использовать Loaded of UserControl для подключения событий (подписаться на Loaded in constructor, подписаться на события кнопки в Loaded).

  • 0
    Если я продолжу так, мне придется подписаться на Loaded в каждом пользовательском элементе управления, который я создаю, и переопределить поведение кнопок в каждом пользовательском элементе управления, чего я не хочу делать. Моя первая цель - определить только один раз в базовом классе поведение editButton
  • 0
    Выше код именно для базового класса. Может быть, вы неправильно поняли мою подписку на Loaded , потому что вы не можете переопределить (нет виртуальной OnLoaded ).
Показать ещё 7 комментариев
0

возможно добавление нового MouseEventHandler к вашему коду:

EditButton.MouseEnter += new MouseEventHandler(EditButton_MouseEnter);
EditButton.MouseLeave += new MouseEventHandler(EditButton_MouseLeave);
  • 0
    Ничего не меняет, я уже пробовал с событием клика (см код)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню