我有一个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方法是存在于FlowDocumentReader所在的MainWindow中的方法,并且想法是按钮的Tag具有一些标识符(库存ID),并且点击处理程序将对该库存ID执行某些操作。
如果FlowDocument位于MainWindow.xaml中,那么这个Button_Click事件处理程序一切正常,但我怀疑当它从磁盘加载文件时,它对处理程序一无所知。
我该如何解决这个问题?想法?
更新
虽然我认为Pavlo的解决方案可行,但我最终做了以下工作,似乎工作得相当好。在我的FlowDocumentReader Xaml中,我添加了以下内容:
<FlowDocumentReader ButtonBase.Click="Button_Click">
并从xaml中删除了按钮的click事件。我仍然在努力解决WPF和XAML问题,但我认为这种常见的点击处理程序可以用于路由事件。当我加载的FlowDocument中的任何按钮发生Click时,它会一直冒泡,直到找到一个处理程序,在我的例子中是FlowDocumentReader元素中指定的处理程序。
尽管我对不理解感到沮丧,但它的工作原理很简洁。
更新2:
依赖于路由事件来处理我的FlowDocument按钮的Click事件的副作用是,作为FlowDocumentReader本身一部分的按钮最终将他们的Click事件冒泡到我创建的这个全能的处理程序中,这是绝对不是我想要发生的事情。
为了解决这个问题,我目前依赖于处理程序中的事实,如下所示:
private void Button_Click(object sender, RoutedEventArgs e)
{
if (e.Source is Button)
{
MessageBox.Show("Button in doc clicked");
}
}
RoutedEventArgs中的“Source”成员是FlowDocument中按钮的“Button”和FlowDocumentReader中属于的那些“FlowDocumentReader”。虽然我有兴趣听取其他想法,但看起来很有用。
答案 0 :(得分:2)
您可以尝试以下操作。为您的按钮命名,并在加载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
属性设置为ID的所有Tag
对象。
答案 1 :(得分:0)
如果您创建自定义按钮类(从按钮派生)并添加您自己的自定义单击事件定义。然后,您可以添加特定于自定义事件的处理程序。无需担心从其他按钮中拾取意外事件。
在按钮类中声明新事件
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" >