Кнопка обработчика нажатия кнопки WPF XAML в проблеме InlineUIContainer - PullRequest
2 голосов
/ 26 января 2011

У меня есть FlowDocument, который имеет несколько элементов, таких как:

<InlineUIContainer>
   <Button Click="Button_Click" Tag="123456789890">
      <Image Source="Images\Image1.png" />
   </Button>
</InlineUIContainer>

Это хранится в файле .xaml и загружается в какой-то момент, делая что-то вроде этого:

flowDocument = XamlReader.Load(xamlFile, parserContext) as FlowDocument;
flowDocumentReader.Document = flowDocument;

Загрузка завершается со следующей ошибкой:

XamlParseException - Не удалось создать «щелчок» из текста «Button_Click»

Метод Button_Click - это метод, который существует в MainWindow, в котором находится FlowDocumentReader, и идея заключается в том, что тег кнопки имеет некоторый идентификатор (идентификатор инвентаря), и обработчик щелчка будет что-то делать с этим идентификатором инвентаря.

Если FlowDocument находится в MainWindow.xaml, все в порядке с этим обработчиком событий Button_Click, но я подозреваю, что когда он загружает файл с диска, он ничего не знает об обработчике.

Как я могу решить это? Идеи?


Обновление

Хотя я думаю, что решение Павла сработает, я закончил тем, что сделал следующее, и, похоже, он работает довольно хорошо. В моем FlowDocumentReader Xaml я добавил следующее:

<FlowDocumentReader ButtonBase.Click="Button_Click">

и удалил событие click из xaml для кнопок. Я все еще борюсь с WPF и XAML, но этот общий обработчик кликов работает, я полагаю, из-за перенаправленных событий. Когда щелчок происходит для любой из кнопок в моем загруженном FlowDocument, он всплывает, пока не найдет обработчик, в моем случае тот, который указан в элементе FlowDocumentReader.

Несмотря на разочарование, которое я испытал от непонимания, очень приятно, что оно работает таким образом.


Обновление 2:

Побочным эффектом использования перенаправленных событий для обработки события Click для кнопок моего FlowDocument является то, что кнопки, являющиеся частью самого FlowDocumentReader, в конечном итоге превращают свои события Click в этот обработчик, созданный мной, который является определенно не то, что я хочу, чтобы произошло.

Чтобы решить эту проблему, я в настоящее время полагаюсь на то, что в обработчике, который выглядит так:

private void Button_Click(object sender, RoutedEventArgs e)
{
   if (e.Source is Button)
   {
      MessageBox.Show("Button in doc clicked");
   }
}

элементом «Source» в RoutedEventArgs является «Button» для кнопок в FlowDocument и «FlowDocumentReader» для тех, которые являются частью FlowDocumentReader. Кажется, работает, хотя мне было бы интересно услышать другие идеи.

Ответы [ 2 ]

2 голосов
/ 26 января 2011

Вы можете попробовать следующее. Дайте название своей кнопке, и после загрузки FlowDocument используйте FindName, чтобы извлечь кнопку и подключить обработчик Click.

<InlineUIContainer>
   <Button x:Name="MyButton" Tag="123456789890">
      <Image Source="Images\Image1.png" />
   </Button>
</InlineUIContainer>

-

flowDocument = XamlReader.Load(xamlFile, parserContext) as FlowDocument;
flowDocumentReader.Document = flowDocument;

Button myButton = (Button)flowDocument.FindName("MyButton");
myButton.Click = Button_Click;

Если ваша кнопка не уникальна и вы не можете дать ей имя, попробуйте найти в документе все объекты типа Button, для свойства Tag которых установлено значение ID.

0 голосов
/ 26 мая 2011

Если вы создаете собственный класс кнопки (производный от кнопки) и добавляете свое собственное определение события щелчка. Затем вы можете просто добавить обработчик, специфичный для вашего пользовательского события. Не нужно беспокоиться о получении непреднамеренных событий от других кнопок.

Объявите новое событие в вашем классе кнопок

 Public Shared ReadOnly ButtonClickEvent As RoutedEvent = _
               EventManager.RegisterRoutedEvent("ButtonClick", RoutingStrategy.Bubble, _
               GetType(RoutedEventHandler), GetType(MyButton))

' Provide CLR accessors for the event
Public Custom Event ButtonClick As RoutedEventHandler
    AddHandler(ByVal value As RoutedEventHandler)
        Me.AddHandler(ButtonClickEvent, value)
    End AddHandler

    RemoveHandler(ByVal value As RoutedEventHandler)
        Me.RemoveHandler(ButtonClickEvent, value)
    End RemoveHandler

    RaiseEvent(ByVal sender As Object, ByVal e As RoutedEventArgs)
        Me.RaiseEvent(e)
    End RaiseEvent
End Event

В обработчике кликов вашего пользовательского класса кнопок поднимите новый RoutedEvent

    Private Sub MyButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        RaiseEvent ButtonClick(Me, New RoutedEventArgs(MyButton.ButtonClickEvent))
    End Sub

Прослушивание для этого с помощью обработчика событий в FlowDocumentReader или другого элемента верхнего уровня. (У меня есть GroupBox вокруг моей программы просмотра документов потока, и я добавил обработчик на этом уровне)

 <GroupBox Header="Document editor" local:MyButton.ButtonClick="OnButtonClick" >
...