Триггеры событий в привязке WPF не работают

#c# #wpf #xaml

#c# #wpf #xaml

Вопрос:

У меня проблема с триггерами событий WPF:

в моем xaml я получил стрелку:

 <Path Data="{Binding Path=Points, Converter={StaticResource ResourceKey=pointCollectionConverter}}"
              Stroke="Black"
              MinWidth="1"
              MinHeight="1"
              Name="arrowPath"
              StrokeThickness="2">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseLeftButtonDown">
                    <cmd:EventToCommand Command="{Binding Path=ArrowPathMouseLeftButtonDownCommand}"
                                        PassEventArgsToCommand="True"></cmd:EventToCommand>
                </i:EventTrigger>
                <i:EventTrigger EventName="MouseRightButtonDown">
                    <cmd:EventToCommand Command="{Binding Path=ArrowPathMouseRightButtonDownCommand}"
                                        PassEventArgsToCommand="True"></cmd:EventToCommand>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Path>
  

События запускаются, как и ожидалось, и все в порядке. Теперь я получил некоторые Ellypses (в том же xaml), которые должны вести себя точно так же, как стрелка при щелчке правой кнопкой мыши.

Поэтому я добавил в свой xaml для Ellypses часть триггера:

 <ItemsControl ItemsSource="{Binding Points}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <controls:DragCanvas AllowDragOutOfView="True" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Ellipse  Cursor="Hand"
                          Fill="Black"
                          Stroke="Black"
                          StrokeThickness="2"
                          Width="10"
                          Height="10"
                          Visibility="{Binding Visible, Converter={StaticResource ResourceKey=endPointTrimmer}}">
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="MouseRightButtonDown">
                            <cmd:EventToCommand Command="{Binding Path=ArrowPathMouseRightButtonDownCommand}"
                                                PassEventArgsToCommand="True"></cmd:EventToCommand>
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </Ellipse>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
        <ItemsControl.ItemContainerStyle>
            <Style TargetType="ContentPresenter">
                <Setter Property="Canvas.Left"
                        Value="{Binding X, Mode=TwoWay}" />
                <Setter Property="Canvas.Top"
                        Value="{Binding Y, Mode=TwoWay}" />
            </Style>
        </ItemsControl.ItemContainerStyle>
    </ItemsControl>
  

Но я получаю ошибку привязки:

System.Windows.Data Error: 40 : BindingExpression path error: 'ArrowPathMouseRightButtonDownCommand' property not found on 'object' ''ConnectionPoint' (HashCode=54168362)'. BindingExpression:Path=ArrowPathMouseRightButtonDownCommand; DataItem='ConnectionPoint' (HashCode=54168362); target element is 'EventToCommand' (HashCode=42719917); target property is 'Command' (type 'ICommand')

и я не понимаю, почему. Пожалуйста, кто-нибудь, помогите мне

Комментарии:

1. Есть ли у вашего ConnectionPoint класса вызываемое общедоступное свойство ArrowPathMouseRightButtonDownCommand ?

2. нет, моя viewmodel содержит это свойство. Но я не понимаю, почему он ищет это свойство в моем классе connectionpoint, когда другой триггер просматривается в моей viewmodel.

3. Каков тип данных Points свойства, к которому вы привязываетесь ItemsSource="{Binding Points}" ?

4. Точки имеют тип ObservableCollection<Точка подключения>

5. Это объясняет, почему привязка ищет это свойство в вашем классе ConnectionPoint, а не в viewmodel. Я думаю, что-то подобное {Binding Path=DataContext.ArrowPathMouseRightButtonDownCommand, ElementName=itemsCtrl} может сработать, если вы предоставите свой ItemsControl x:Name="itemsCtrl" свойству.

Ответ №1:

Чтобы получить доступ к той же ViewModel (т.Е. контексту данных), что и the ItemsControl , Вы должны присвоить элементам управления имя, например, вот так:

 <ItemsControl x:Name="itemsCtrl" ...>
  

и затем вы можете использовать следующую привязку для доступа к ArrowPathMouseRightButtonDownCommand свойству в ViewModel:

 {Binding Path=DataContext.ArrowPathMouseRightButtonDownCommand, ElementName=itemsCtrl}
  

Ответ №2:

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

 <cmd:EventToCommand Command="{Binding Path=ArrowPathMouseRightButtonDownCommand,RelativeSource={RelativeSource
                    Mode=FindAncestor,
                    AncestorType=Path}}"
                                                PassEventArgsToCommand="True"></cmd:EventToCommand>
  

Комментарии:

1. Это не сработает, потому что предком path и ItemsControl является сетка. Могу ли я установить тип в grid и установить для источника второй путь в этой сетке?

2. вы можете сослаться на ссылку tonychampion.net/blog/index.php/2011/12 /…