Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
When we have a custom listbox with a defined event-handling for the left-click of the mouse, and also an additional shape inside the ListBoxItem data template which needs to do some action when it is clicked how can we handle these
I have a Custom ListBox witch tries to handle the Click event :
In the ContentView:
<ABC:AListBox
ClickCommand="{Binding LaunchCommand}"
</ABC:AListBox>
In it's datatemplate we have this:
<DataTemplate x:Key="ThisListTemplate">
<StackPanel ...>
<Border Grid.Column="1" VerticalAlignment="Center">
<TextBlock
FontSize="15"
Foreground="White"
Text="{Binding Path=ItemTitle}" />
</Border>
<Canvas Height ="12" Width ="12" >
<Ellipse Name = "TheEllipse" Stroke="Black" Height ="12"
Width ="12" Cursor="Hand" Canvas.Left="185" Canvas.Top="12">
</Ellipse>
<Ellipse.InputBindings>
<MouseBinding Gesture="LeftClick"
Command="{Binding DataContext.LaunchFromXamlCommand , RelativeSource={RelativeSource AncestorType=ABC:AListBox}}"
CommandParameter="{Binding}" />
</Ellipse.InputBindings>
</Canvas>
</StackPanel>
</DataTemplate>
And in the MVVM as our data context we have:
public ICommand LaunchCommand { get; private set; }
public DelegateCommand<object> LaunchFromXamlCommand { get; private set; }
// Initialization on load:
this.LaunchCommand = new DelegateCommand(this.LaunchRun);
this.LaunchFromXamlCommand = new DelegateCommand<object>(this.LaunchFromXamlRun);
//---------
private void LaunchFromXamlRun(object param)
TheListItem app = (TheListItem)param;
private void LaunchRun()
{ ... }
Here I used 2 different commands LaunchCommand as an ICommand in addition with LaunchFromXamlCommand which is called via the template.
The LaunchFromXamlRun
will get triggered fine and as expected.
But also as it can be guessed there will be 2 raised events and 2 commands getting triggered which I want to omit one and ignore the general ListBox event handler when that shape is get hit.
What can be the best solution for doing this?
FYI: (Maybe not so important just for a note) The App is using earlier versions of Prism (don't think that matters here) and has a modular code, everything is separated in different assemblies and the code is using MVVM pattern.
I wish we had something like e.handled = true
in a mechanism that could be used in the given scenario.
–
–
–
–
–
Your problem is exacerbated by having that click handler in your listbox. I don't know how you're doing that but that cannot just be click. It's probably previewmousedown. Because, of course, a listbox "eats" mousedown as part of selecting an item.
One way round this involves not using that listbox previewmousedown. Here I put my row content inside a button and bind the button's command. It doesn't look like a button of course.
I make the circle into a button and give it a transparent fill so you can click on all of it.
<ListBox ItemsSource="{Binding People}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Button Command="{Binding DataContext.ItemClickCommand, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}"
CommandParameter="{Binding}"
<Button.Template>
<ControlTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding LastName}"/>
<Button Command="{Binding DataContext.EllipseCommand, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}"
<Button.Template>
<ControlTemplate>
<Ellipse Name = "TheEllipse" Stroke="Black"
Fill="Transparent"
Height ="12"
Width="12" Cursor="Hand">
</Ellipse>
</ControlTemplate>
</Button.Template>
</Button>
</StackPanel>
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
My viewmodel uses relaycommands but (obviously) any implementation of ICommand would do. I had People from the last question I did some work on.
public class MainWindowViewModel : BaseViewModel
private RelayCommand ellipseCommand;
public RelayCommand EllipseCommand
return ellipseCommand
?? (ellipseCommand = new RelayCommand(
Console.WriteLine("CIRCLE clicked");
private RelayCommand<Person> itemClickCommand;
public RelayCommand<Person> ItemClickCommand
return itemClickCommand
?? (itemClickCommand = new RelayCommand<Person>(
(person) =>
Console.WriteLine($"You clicked {person.LastName}");
person.IsSelected = true;
private ObservableCollection<Person> people = new ObservableCollection<Person>();
public ObservableCollection<Person> People
get { return people; }
set { people = value; }
public ListCollectionView LCV { get; set; }
public MainWindowViewModel()
People.Add(new Person { FirstName = "Chesney", LastName = "Brown" });
People.Add(new Person { FirstName = "Gary", LastName = "Windass" });
People.Add(new Person { FirstName = "Liz", LastName = "McDonald" });
People.Add(new Person { FirstName = "Carla", LastName = "Connor" });
When you click that outer button it will grab the click. Which is why I set IsSelected in the command so the item you click becomes selected via binding.
–
–
–
–
–
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.