Событие MouseLeftButtonDown не запускается в дочернем ContentControl

У меня есть PortItem, полученное из ContentControl, TextedStackPanel, полученное из StackPanel, которое содержит PortItems. А в MainWindow у меня есть 2 StackPanels, которые содержат TextedStackPanels. В PortItem я переопределил метод MouseLeftButtonDown. Но когда я делаю это, этот метод не запускается. Я искал здесь на форуме и обнаружил, что для свойства Background Grid/StackPanel должно быть установлено значение Transparent. Я применил это, но нет никаких изменений. Что делать ?

EDIT 1 Я использую частичные классы. У меня 2 класса: PortItem.cs и PortItem.cs.xaml. Я изменяю любые визуальные изменения в этом файле XAML.

EDIT 2 Также не запускаются никакие события мыши. Триггеры, которые я использую IsMouseOver, также не работают, когда я держу мышь на PortItem

XAML

<ContentControl x:Class="**.PortItem"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:UI="clr-namespace:**.UIData" Width="17" Height="17" Margin="3" SnapsToDevicePixels="True" >
<Grid Background="Transparent" Name="mainGrid">
    <!-- transparent extra space makes connector easier to hit -->
    <Rectangle Fill="Transparent" Margin="-2"/>
    <Border BorderBrush="Green" x:Name="border" BorderThickness="2">
        <Border.Style>
            <Style>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Grid}, Path=IsMouseOver}" Value="True">
                        <Setter  Property="Border.BorderBrush" Value="Blue"/>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding IsSelected}" Value="True">
                        <Setter  Property="Border.BorderBrush" Value="Blue"/>
                    </DataTrigger>
                    <!--<DataTrigger Binding="{Binding ContactPort}" Value="{x:Null}">
            <Setter TargetName="border" Property="Border.BorderBrush" Value="Green"/>
        </DataTrigger>-->
                </Style.Triggers>
            </Style>
        </Border.Style>
            <Image  Source="/**;component/Resources/1337238611_port.png">
        </Image>
    </Border>
</Grid>


person Rabi    schedule 12.06.2012    source источник
comment
Так это прозрачная область вокруг вашего элемента управления, которую вы должны щелкнуть? попробуйте добавить ClipToBounds=False в сетку, чтобы убедиться, что прямоугольник не обрезается до его границ.   -  person Andy    schedule 12.06.2012
comment
да, я сделал фон всех панелей/сеток прозрачным. но это все равно не работает. я проверю то, что вы сказали выше   -  person Rabi    schedule 13.06.2012


Ответы (2)


Убедитесь, что вы не установили для IsHitTestVisible значение false в вашем PortItem. Кроме того, убедитесь, что на нем нет других элементов управления. Если это так, установите для свойства IsHitTestVisible значение false, и тогда ваш элемент управления PortItem получит событие щелчка правой кнопкой мыши. Чтобы убедиться, что сверху ничего нет, объявите свой объект PortItem последним, добавленным в TextedStackPanel. Чтобы еще раз убедиться, что сверху ничего нет, измените цвет фона других элементов управления на что-то действительно заметное (просто для тестирования), чтобы увидеть, не закрывает ли что-либо ваш элемент управления PortItem. Кроме того, измените цвет элемента управления PortItem, чтобы убедиться, что он действительно находится там, где вы думаете. Затем, как только вы все заработаете, измените цвета на исходные.

Если бы вы могли предоставить нам пример кода вашего XAML, это могло бы помочь. Если вы добавляете PortItems динамически в код позади, также укажите этот код.

person Curtis    schedule 12.06.2012

Изменить: в свете изменений, которые вы внесли в свой код, попробуйте добавить ClipToBounds="False" в верхнюю часть объявления пользовательского элемента управления.

<ContentControl x:Class="**.PortItem" ClipToBounds="False"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:UI="clr-namespace:**.UIData" Width="17" Height="17" Margin="3" SnapsToDevicePixels="True" >

Вы создали шаблон для вашего PortItem? Я создал следующий класс для репликации вашего PortItem и точки останова в строке base.OnMouseButtonDown, и он срабатывает, я думаю, что причина, по которой ваш метод не выполняется, заключается в том, что нет визуального элемента, с которым мышь могла бы фактически взаимодействовать, попробуйте добавить стиль ниже к вашему приложению, и вы должны увидеть правильное срабатывание метода.

   public class PortItem: ContentControl
    {
        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {

            base.OnMouseLeftButtonDown(e);
        }
    }

затем в XAML я создал стиль, чтобы дать ему что-то для рендеринга.

 <local:PortItem Margin="44,36,156,95">
        <local:PortItem.Style>
            <Style TargetType="{x:Type local:PortItem}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type local:PortItem}">
                            <Border Background="Transparent">
                                <ContentPresenter Content="{TemplateBinding Content}"/>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </local:PortItem.Style>
    </local:PortItem>

Прозрачный фон, который вы упомянули, вы можете видеть в пограничном контроле, если вы оставите фон, вы правы, событие никогда не срабатывает.

person Andy    schedule 12.06.2012
comment
это не помогло. имеют сложную структуру. Сетки, StackPanels в нем, а также другие панели. И, наконец, это ContentControl, который я дал XAML. любые другие решения? - person Rabi; 14.06.2012