ฉันกำลังพยายามสร้าง ContextMenu ที่สามารถนำมาใช้ซ้ำได้สำหรับแต่ละองค์ประกอบของอาร์เรย์ดังนี้:
<ContextMenu>
<ContextMenu.Resources>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Command" Value="{Binding UpdateFooInfoCommand}"/>
<Setter Property="CommandParameter" Value="{Binding MyViewModel.FooInfo[0]}" />
</Style>
</ContextMenu.Resources>
<MenuItem
Header="Blocked"
IsEnabled="{Binding MyViewModel.FooInfo[0].CurrentlyEnabled, Converter={StaticResource ContainsValueConverter}, ConverterParameter={x:Static entities:FooStatus.Blocked}}"
IsChecked="{Binding MyViewModel.FooInfo[0].CurrentlySelected, Mode=TwoWay, Converter={StaticResource ContainsValueConverter}, ConverterParameter={x:Static entities:FooStatus.Blocked}}"
/>
<MenuItem
Header="Working"
IsEnabled="{Binding MyViewModel.FooInfo[0].CurrentlyEnabled, Converter={StaticResource ContainsValueConverter}, ConverterParameter={x:Static entities:FooStatus.Working}}"
IsChecked="{Binding MyViewModel.FooInfo[0].CurrentlySelected, Mode=TwoWay, Converter={StaticResource ContainsValueConverter}, ConverterParameter={x:Static entities:FooStatus.Working}}"
/>
<MenuItem
Header="Sleeping"
IsEnabled="{Binding MyViewModel.FooInfo[0].CurrentlyEnabled, Converter={StaticResource ContainsValueConverter}, ConverterParameter={x:Static entities:FooStatus.Sleeping}}"
IsChecked="{Binding MyViewModel.FooInfo[0].CurrentlySelected, Mode=TwoWay, Converter={StaticResource ContainsValueConverter}, ConverterParameter={x:Static entities:FooStatus.Sleeping}}"
/>
</ContextMenu>
โดยใช้ :
[Flags]
public enum FooStatus : byte
{
None = 0,
Sleeping = 1 << 0,
Working = 1 << 1,
Blocked = 1 << 4
}
แต่อย่างที่คุณเห็นว่าฉันกำลังใช้อาร์เรย์ทุกที่ ดังนั้นจึงไม่มีทางที่จะใช้ contextMenu นี้ซ้ำได้ แต่ใช้การคัดลอกและวางและเปลี่ยนดัชนี เพื่อหลีกเลี่ยงไม่ให้มีการอ้างอิงอาร์เรย์จำนวนมาก ฉันลองทำสิ่งนี้:
<ContextMenu DataContext="{Binding PlacementTarget.DataContext.MyViewModel.FooInfo[0], RelativeSource={RelativeSource Self}}">
<ContextMenu.Resources>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Command" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type Control}, Mode=FindAncestor, AncestoLevel=2}, Path=DataContext.UpdateFooInfoCommand }" />
<Setter Property="CommandParameter" Value="{Binding}" />
</Style>
</ContextMenu.Resources>
.....
</ContextMenu>
นั่นทำให้ฉันมีบริบทข้อมูลดังนั้นฉันจึงไม่จำเป็นต้องอ้างอิงอาร์เรย์ทุกที่อีกต่อไป แต่ฉันยังคงหลงลืมวิธีทำให้คำสั่งทำงานเหมือนเมื่อก่อนและจัดเก็บทรัพยากรนี้สำหรับการใช้งานหลายครั้งและเพียงแค่เปลี่ยนบริบทข้อมูล
แก้ไข
<ContextMenu DataContext="{Binding PlacementTarget.DataContext.MyViewModel.FooInfo[0], RelativeSource={RelativeSource Self}}"
Tag="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
<ContextMenu.Resources>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Command" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ContextMenu}}, Path=Tag.UpdateFooInfoCommand}"/>
<Setter Property="CommandParameter" Value="{Binding}" />
</Style>
</ContextMenu.Resources>
.....
</ContextMenu>
ฉันพบวิธีการอ่านเกี่ยวกับ PlacementTarget ไม่รู้ว่าเมนูบริบทไม่ได้เป็นส่วนหนึ่งของแผนผัง แต่ฉันยังไม่มีเบาะแสเกี่ยวกับวิธีการสร้างเมนูบริบทนี้
ContextMenue
ได้โดยใส่ไว้ในDataTemplate
สำหรับเป้าหมาย หรือในStyle
สำหรับ (เช่น)ListViewItem
หรือสิ่งที่คุณมี แน่นอน หากคุณทำเช่นนั้น คุณจะเลิกสนใจว่ารายการปัจจุบันจะอยู่ในตำแหน่งใดในอาร์เรย์ของคุณ เพราะคุณสามารถเชื่อมโยงกับรายการปัจจุบันได้อย่างง่ายดาย - person mcwyrm   schedule 22.02.2014