In some situation. I need to select DoubleClick
control like button. And it fill the ListBoxItem
.
I couldn't set IsHitTestVisible = "false"
cause I need to DoubleClick
it.
Code like:
<ListBox>
<Button Width="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}, Path=ActualWidth}" />
</ListBox>
What the best way to handle it? better in MVVM.
PS: Select item by clicking item.
I have tried to set 'e.Handled = false;' in click event, let it go to the selector. But it didn't work.
I found a way that could let item be selected and do somethings in 'Double Click' .
1.
First, the item need set 'IsHitTestVisible="False"' .
Second, we write a 'MouseDoubleClick' in 'Listbox' and item. And we find the item in 'ListboxMouseDoubleClick' to trigger item 'MouseDoubleClick'.
In xaml
<ListBox MouseDoubleClick="ListboxDoubleClick">
<TextBlock Text="Try Select Need Double Click item"/>
<Button Background="Red" MouseDoubleClick="BtnInListBoxDoubleClick" IsHitTestVisible="False" Width="{Binding RelativeSource={RelativeSource AncestorType=ListBox}, Path=ActualWidth}" Height="20" />
</ListBox>
MouseDoubleClick:
private void BtnInListBoxDoubleClick(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("This is BtnInListBoxDoubleClick!");
}
private void ListboxDoubleClick(object sender, MouseButtonEventArgs e)
{
DependencyObject originalSource = e.OriginalSource as DependencyObject;
var btn = FindControlHelper.FindChild<Button>(originalSource) as Button;
if (btn == null)
return;
var mouseEventArgs = new MouseButtonEventArgs
(Mouse.PrimaryDevice, Environment.TickCount, MouseButton.Left)
{
RoutedEvent = Button.MouseDoubleClickEvent,
Source = btn
};
btn.RaiseEvent(mouseEventArgs);
}
FindChild function:
public static T? FindChild<T>(DependencyObject dependencyObject, string? name = null)
where T : FrameworkElement
{
DependencyObject? child = null;
T? grandChild = null;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject); i++)
{
child = VisualTreeHelper.GetChild(dependencyObject, i);
if (child is T && (((T)child).Name == name | string.IsNullOrEmpty(name)))
{
return (T)child;
}
else
{
grandChild = FindChild<T>(child, name);
if (grandChild != null)
return grandChild;
}
}
return null;
}
So the point is set your item 'IsHitTestVisible="False"' so that item could be selected, then find the item in 'ListBox' 's 'DoubleClickEvent'.
2 .
And by the way , if you could find the item that mean you could find the item's 'DataContext'. So you don't need to operate directly control in View.
like:
var listboxitem = FindControlHelper.FindParent<ListBoxItem>(originalSource) as ListBoxItem;
if (listboxitem == null)
return;
var datacontext = listboxitem.DataContext as Student;
FindParent function:
public static T? FindParent<T>(DependencyObject dependencyObject, string? name = null)
where T : FrameworkElement
{
var parent = VisualTreeHelper.GetParent(dependencyObject);
while (parent != null)
{
if (parent is T && (((T)parent).Name == name | string.IsNullOrEmpty(name)))
{
return (T)parent;
}
parent = VisualTreeHelper.GetParent(parent);
}
return null;
}