首页 > 解决方案 > 自定义控件中的按钮在添加到画布时丢失其事件绑定

问题描述

我使用以下 XAML 构建了一个自定义控件

<StackPanel Name="spTop">
    <Button Name="btnDBConfiguration" HorizontalAlignment="Center" Background="Transparent" HorizontalContentAlignment="Left" MouseEnter="btnDBConfiguration_MouseEnter" MouseLeave="btnDBConfiguration_MouseLeave"  >
        <StackPanel Orientation="Vertical">
            <Image Source="/Images/DBImport25px.png" Width="40" Height="40" VerticalAlignment="Center" HorizontalAlignment="Center" Name="imgVerify"></Image>
            <TextBlock Foreground="AntiqueWhite" Background="Black" VerticalAlignment="Center" Name="tblkConnectionName" >Database</TextBlock>
        </StackPanel>
    </Button>
    <!--
    <StackPanel Orientation="Vertical" HorizontalAlignment="Center" Name="DBImport">
        <Image Source="/Images/DBImport25px.png" VerticalAlignment="Center" HorizontalAlignment="Center"></Image>
        <TextBlock Text="Database" Foreground="AntiqueWhite"/>
    </StackPanel>-->
    <Border BorderBrush="Gray" BorderThickness="1"  Width="50">
        <StackPanel Orientation="Horizontal" Name="spButtonBar" MouseEnter="btnDBConfiguration_MouseEnter" MouseLeave="btnDBConfiguration_MouseLeave" >
            <Button Name="btnDBConnection" HorizontalAlignment="Left" Background="Transparent"   HorizontalContentAlignment="Left" ToolTip="DB Connection" Click="btnDBConnection_Click" >
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
                <Image Source="/Images/dbConfig25px.png" VerticalAlignment="Center" HorizontalAlignment="Left" Name="imgDBConnection"></Image>
            </StackPanel>
        </Button>
    </StackPanel>
</Border>
</StackPanel>

当我使用此行手动将其添加到画布时,此控件内的按钮将起作用:

        <Control:dbButtonControl Grid.Column="1" VerticalAlignment="Center" />

但是,当我使用此代码通过拖放动态添加它时:

        dbButtonControl cntrlDBButton = new dbButtonControl();
        cntrlDBButton.SetNameText(ObjectTitle);
        cntrlDBButton.PreviewMouseDown += CnvsLinkScreen_PreviewMouseDown;

        Canvas.SetLeft(cntrlDBButton, pntEnterPoint.X);
        Canvas.SetTop(cntrlDBButton, pntEnterPoint.Y);

        cnvsLinkScreen.Children.Add(cntrlDBButton);

自定义控件中的按钮不再起作用。我添加了一个 previewmousedown 事件,因此我可以单击并在页面周围拖动控件。我禁用了此事件,控件中的按钮再次开始工作。所以看起来我添加的预览鼠标按钮事件导致了它。但我确实需要启用它并使控件中的按钮仍然有效。我该如何解决这个问题?

标签: c#wpf

解决方案


结果证明这是一个更复杂的问题,我想尝试通过应用程序和控件之间的事件处理来控制它。所以我做的很简单...

我创建了一个网格,其中包括我的自定义控件和一个“抓取”按钮。

        Grid gdTab = new Grid();
        //gdTab.Name = ObjectTitle;
        Image imgGripper = new Image();
        imgGripper.Source = new BitmapImage(new Uri(@"pack://application:,,,/images/Dot25px.png", UriKind.Absolute));
        imgGripper.Width = 15;
        imgGripper.Height = 15;
        imgGripper.VerticalAlignment = VerticalAlignment.Top;
        imgGripper.HorizontalAlignment = HorizontalAlignment.Left;
        imgGripper.MouseEnter += (s,e) => Mouse.OverrideCursor = Cursors.Hand;
        imgGripper.MouseLeave += (s, e) => Mouse.OverrideCursor = Cursors.Arrow;
        imgGripper.MouseEnter += ImgGripper_MouseEnter;
        imgGripper.MouseLeave += ImgGripper_MouseLeave;

        Canvas.SetLeft(gdTab, pntEnterPoint.X);
        Canvas.SetTop(gdTab, pntEnterPoint.Y);
        gdTab.Children.Add(cntrlDBButton);
        gdTab.Children.Add(imgGripper);
        cnvsLinkScreen.Children.Add(gdTab);

然后我将 MouseEnter 和 MouseLeave 映射到方法:

    private void ImgGripper_MouseEnter(object sender, MouseEventArgs e)
    {
        Grid gdSender = (Grid)((Image)sender).Parent;
        if (gdSender != null)
            gdSender.PreviewMouseDown += CnvsLinkScreen_PreviewMouseDown;
    }

    private void ImgGripper_MouseLeave(object sender, MouseEventArgs e)
    {
        Grid gdSender = (Grid)((Image)sender).Parent;
        if (gdSender != null)
            gdSender.PreviewMouseDown -= CnvsLinkScreen_PreviewMouseDown;
    }

这样,拖动选项仅在鼠标位于小抓取区域上时可用。

然后我修改了移动代码以移动创建的带有控件的网格。一旦鼠标离开圆圈,控件的按钮将再次起作用。


推荐阅读