Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 为什么;在Setter.Value结构中设置事件处理程序;给出编译错误?_Wpf_Events_Styles - Fatal编程技术网

Wpf 为什么;在Setter.Value结构中设置事件处理程序;给出编译错误?

Wpf 为什么;在Setter.Value结构中设置事件处理程序;给出编译错误?,wpf,events,styles,Wpf,Events,Styles,我面临的问题与中描述的完全一样。但是我想理解为什么问题作者提供的解决方案不起作用。看起来我遗漏了一些概念。这似乎是XAML代码生成过程中的一个错误。除了XAML文件的用户代码之外,还有一个“编译器”生成的版本,它为命名元素(即x:Name)定义InitializeComponent和class字段 举一个简单的例子: <Window.Resources> <Style TargetType="Button"> <Setter Property

我面临的问题与中描述的完全一样。但是我想理解为什么问题作者提供的解决方案不起作用。看起来我遗漏了一些概念。

这似乎是XAML代码生成过程中的一个错误。除了XAML文件的用户代码之外,还有一个“编译器”生成的版本,它为命名元素(即x:Name)定义InitializeComponent和class字段

举一个简单的例子:

<Window.Resources>
    <Style TargetType="Button">
        <Setter Property="ContextMenu">
            <Setter.Value>
                <ContextMenu>
                    <MenuItem Header="Header" Click="MenuItem_Click"/>
                </ContextMenu>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

<Button />
生成的代码隐藏文件可以在
obj
文件夹中找到,因此,如果我们进行检查,可以看到以下代码:

void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
    switch (connectionId)
    {
    case 1:

    #line 13 "..\..\..\MainWindow.xaml"
    ((System.Windows.Controls.Button)(target)).AddHandler(System.Windows.Controls.MenuItem.ClickEvent, new System.Windows.RoutedEventHandler(this.MenuItem_Click));

    #line default
    #line hidden
    return;
    }
    this._contentLoaded = true;
}
这里的问题是生成的代码试图将
菜单项
强制转换为
按钮
。如果我们这样更改我们的样品:

<Window.Resources>
    <ContextMenu x:Key="ContextMenuKey">
        <MenuItem Header="Header" Click="MenuItem_Click"/>
    </ContextMenu>

    <Style TargetType="Button">
        <Setter Property="ContextMenu"
                Value="{StaticResource ContextMenuKey}" />
    </Style>
</Window.Resources>

<Button />
根据我的测试,代码生成器似乎为每个需要“连接”或添加处理程序/备份字段的控件分配了一个ID。在ContextMenu包含在内联中的情况下(即第一个示例),它的事件处理程序被分配给窗口内的根元素,而没有获得它自己的ID

如果我们将按钮更改为包含在网格中,那么上面的异常将表明它无法将MenuItem强制转换为网格。因为现在网格是根元素。这表示它与样式目标的类型无关

当ContextMenu作为一个单独的资源包含时,代码生成器似乎会正确地为其分配一个ID,以便可以正确地附加其处理程序


归根结底,这是XAML代码生成器中的一个错误。

如果加载Wpf相关程序集失败(Xceed.Wpf.Toolkit.dll用于不命名它),也会发生此问题。

通过“问题作者提供的解决方案”您的意思是,这样附加处理程序是不可行的,对吗?(只是为了避免混淆,因为我确实提供了一个“解决方案”,其中涉及到使用
事件设置器
,这确实有效)感谢您的精彩解释。我想你可以把这个bug提交给wpf开发者。
<Window.Resources>
    <ContextMenu x:Key="ContextMenuKey">
        <MenuItem Header="Header" Click="MenuItem_Click"/>
    </ContextMenu>

    <Style TargetType="Button">
        <Setter Property="ContextMenu"
                Value="{StaticResource ContextMenuKey}" />
    </Style>
</Window.Resources>

<Button />
void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
    switch (connectionId)
    {
    case 1:

    #line 10 "..\..\..\MainWindow.xaml"
    ((System.Windows.Controls.MenuItem)(target)).Click += new System.Windows.RoutedEventHandler(this.MenuItem_Click);

    #line default
    #line hidden
    return;
    }
    this._contentLoaded = true;
}