#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
, область считается принадлежащей самому окну, и тогда события мыши не возникают.