ฉันพบวิธีที่ง่ายและสะอาดมากในการดำเนินการนี้ด้วยทริกเกอร์ Blend SDK Event ทำความสะอาด MVVM ใช้ซ้ำได้และไม่มีรหัสหลัง
คุณอาจมีสิ่งนี้อยู่แล้ว:
<Style x:Key="MyListStyle" TargetType="{x:Type ListViewItem}">
ตอนนี้รวม ControlTemplate สำหรับ ListViewItem เช่นนี้หากคุณยังไม่ได้ใช้:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<GridViewRowPresenter Content="{TemplateBinding Content}"
Columns="{TemplateBinding GridView.ColumnCollection}" />
</ControlTemplate>
</Setter.Value>
</Setter>
GridViewRowPresenter จะเป็นรากภาพขององค์ประกอบทั้งหมด "ภายใน" ซึ่งประกอบเป็นองค์ประกอบแถวรายการ ตอนนี้เราสามารถแทรกทริกเกอร์ที่นั่นเพื่อค้นหาเหตุการณ์ที่กำหนดเส้นทาง MouseDoubleClick และเรียกคำสั่งผ่าน InvokeCommandAction ดังนี้:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<GridViewRowPresenter Content="{TemplateBinding Content}"
Columns="{TemplateBinding GridView.ColumnCollection}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction Command="{Binding DoubleClickCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</GridViewRowPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>
หากคุณมีองค์ประกอบภาพ "ด้านบน" GridRowPresenter (probalby เริ่มต้นด้วยเส้นตาราง) คุณสามารถวาง Trigger ไว้ที่นั่นได้
น่าเสียดายที่เหตุการณ์ MouseDoubleClick ไม่ได้สร้างขึ้นจากทุกองค์ประกอบภาพ (มาจาก Controls แต่ไม่ใช่จาก FrameworkElements เป็นต้น) วิธีแก้ปัญหาคือการได้รับคลาสจาก EventTrigger และมองหา MouseButtonEventArgs ด้วย ClickCount เป็น 2 สิ่งนี้จะกรองสิ่งที่ไม่ใช่ MouseButtonEvents และ MoseButtonEvents ทั้งหมดออกอย่างมีประสิทธิภาพด้วย ClickCount! = 2
class DoubleClickEventTrigger : EventTrigger
{
protected override void OnEvent(EventArgs eventArgs)
{
var e = eventArgs as MouseButtonEventArgs;
if (e == null)
{
return;
}
if (e.ClickCount == 2)
{
base.OnEvent(eventArgs);
}
}
}
ตอนนี้เราสามารถเขียนสิ่งนี้ได้แล้ว ('h' คือเนมสเปซของคลาสตัวช่วยด้านบน):
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<GridViewRowPresenter Content="{TemplateBinding Content}"
Columns="{TemplateBinding GridView.ColumnCollection}">
<i:Interaction.Triggers>
<h:DoubleClickEventTrigger EventName="MouseDown">
<i:InvokeCommandAction Command="{Binding DoubleClickCommand}" />
</h:DoubleClickEventTrigger>
</i:Interaction.Triggers>
</GridViewRowPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>