Команда события двойного щелчка не всегда выполняется

#c# #wpf

#c# #wpf

Вопрос:

Я совсем новичок в WPF и C #. Я пытаюсь перехватить событие двойного щелчка в пользовательском элементе управления и обработать его с помощью ICommand.

Вот как я пытаюсь это сделать:

Пользовательский контроль:

 <UserControl x:Class="MyNamespace.View.MyUserControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
         xmlns:local="clr-namespace:MyNamespace.View"
         mc:Ignorable="d" 
         d:DesignHeight="450" d:DesignWidth="800"
         xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
         DataContext="{Binding MyViewModelClass, Source={StaticResource Locator}}"
         >
<UserControl.Resources>
    <DataTemplate x:Key="MyTemplate">
        <ContentControl>
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseDoubleClick">
                    <i:InvokeCommandAction  Command="{Binding DataContext.HandleDoubleClickCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>

            <WrapPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="12" >

                <TextBlock Text="Data: "><Run FontWeight="Light" Text="{Binding data}"/></TextBlock>

        </WrapPanel>
        </ContentControl>
    </DataTemplate>
</UserControl.Resources>

<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="{DynamicResource ColorPanel2}">
    <Grid.RowDefinitions>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Border Grid.Row="0"  BorderThickness="0 0 0 1">
        <WrapPanel Margin="12" VerticalAlignment="Center">
            <TextBlock FontWeight="Bold" Margin="8" VerticalAlignment="Center" FontSize="18"
                       Text="some text: ">
            </TextBlock>
        </WrapPanel>
    </Border>

    <ListView Grid.Row="1" 
              HorizontalAlignment="Stretch" 
              VerticalAlignment="Stretch" 
             ItemsSource="{Binding SelectedItem.listElement, UpdateSourceTrigger=PropertyChanged}"
              ItemTemplate="{StaticResource MyTemplate}"
              SelectedItem="{Binding SelectedItem}"
            />

</Grid>
</UserControl>
 

И я поместил команду для обработки события в класс ViewModel:

 ICommand _HandleDoubleClickCommand;
public ICommand HandleDoubleClickCommand
{
    get
    {
        if (_HandleDoubleClickCommand == null)
        {
            _HandleDoubleClickCommand = new RelayCommand<object>(ExecuteHandleDoubleClickCommand, CanExecuteHandleDoubleClickCommand);
        }
        return _HandleDoubleClickCommand;
    }
}

private bool CanExecuteHandleDoubleClickCommand(object arg)
{
    return true;
}

private void ExecuteHandleDoubleClickCommand(object obj)
{
    System.Windows.MessageBox.Show("HandleDoubleClickCommand");
}
 

Итак, в основном у меня есть список элементов, и я хочу обработать событие двойного щелчка на is.
Поведение, которое я вижу, заключается в том, что иногда выполняется HandleDoubleClickCommand, иногда нет. Я не вижу никаких исключений, и я проверил с помощью отладчика, что код выполняется только при отображении окна сообщения.

Я также пытался использовать InputBindings вместо взаимодействия.Триггеры:

 <ContentControl.InputBindings>
<MouseBinding MouseAction="LeftDoubleClick"
    Command="{Binding DataContext.HandleDoubleClickCommand, RelativeSource={RelativeSource AncestorType=UserControl}, diag:PresentationTraceSources.TraceLevel=High}" />
 

Но я вижу такое же поведение. Включение TraceLevel=High не дало мне полезной информации..
Кроме того, я пытался обработать событие щелчка правой кнопкой мыши вместо двойного щелчка, но, тем не менее, команда выполняется только иногда.

Я думаю, что я что-то здесь упускаю, может кто-нибудь помочь мне понять, в чем проблема? или, по крайней мере, дайте мне несколько советов о том, как я могу устранить проблему..
Спасибо

Обновить
Я обнаружил, что команда всегда выполняется, если я дважды щелкаю по тексту элемента. Дело в том, что я бы хотел, чтобы она выполнялась, даже если я дважды щелкну по пустому месту выбранной строки ListView…

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

1. Где вы дважды щелкаете, когда это не работает? Попробуйте установить значение Background WrapPanel Transparent . Тогда команда должна вызываться всякий раз, когда вы щелкаете внутри WrapPanel .

2. Я попытался сделать фон прозрачным, но это ничего не изменило. Но установка для нее желтого цвета заставила меня заметить одну вещь: двойной щелчок работает, когда я делаю это над текстом элемента списка. Чего я хотел бы добиться, так это обработать двойной щелчок по всей строке выбранного элемента … вместо этого я попытался поместить InputBindings в ListView, но у меня противоположное поведение: команда выполняется только тогда, когда я нажимаю за пределами выбранных элементов, то есть в пустом пространстве списка

3. Очевидно, что команда не будет вызываться при нажатии в любом месте за пределами WrapPanel .

4. конечно, дело в том, что элемент ListView в основном представляет собой строку .. я ожидал, что панель-оболочка будет расширяться на всю ширину строки, но это не так, я хочу, чтобы моя команда вызывалась при двойном щелчке в любом месте элемента, я не нашел способа привязать команду к ListViewэлемент, ни для того, чтобы панель-оболочка заполняла всю строку.. На самом деле я пробую разные вещи, используя разные элементы управления вместо WrapPanel, но пока я не нашел способа решить свою проблему. Похоже, что привязка команды к элементу ListView не так проста, как я изначально думал..

Ответ №1:

Переместите Margin из WrapPanel в TextBlock и определите ItemContainerStyle , чтобы содержимое ListViewItem растягивалось по горизонтали.

Вы также должны установить Background свойство WrapPanel для захвата щелчков:

 <ListView Grid.Row="1" 
          HorizontalAlignment="Stretch" 
          VerticalAlignment="Stretch" 
          ItemsSource="{Binding SelectedItem.listElement}"
          SelectedItem="{Binding SelectedItem}">
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="HorizontalContentAlignment" Value="Stretch" />
        </Style>
    </ListView.ItemContainerStyle>
    <ListView.ItemTemplate>
        <DataTemplate>
            <ContentControl>
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="MouseDoubleClick">
                        <i:InvokeCommandAction  Command="{Binding DataContext.HandleDoubleClickCommand, 
                            RelativeSource={RelativeSource AncestorType=UserControl}}"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
                <WrapPanel Background="Transparent">
                    <TextBlock Text="Data: " Margin="12"><Run FontWeight="Light" Text="{Binding data}"/></TextBlock>
                </WrapPanel>
            </ContentControl>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>
 

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

1. Это потрясающе! это именно то, что мне было нужно! большое вам спасибо 🙂 Просто мне непонятно, почему свойство Background имеет какое-либо отношение к захвату события … я имею в виду, разве элемент управления не имеет фона по умолчанию?

2. @giocarmine: Нет, если вы не установите Background , область считается принадлежащей самому окну, и тогда события мыши не возникают.