我正在使用 WinUI3 和 C# 开发一个应用程序。 我想将快捷方式的动态设置渲染添加到我的应用程序中。因此,我使用 ItemsRepeater 和 DataTemplate 来呈现多个设置面板。这一切似乎都有效。
XAML:
<Grid>
<StackPanel Orientation="Vertical">
<ItemsRepeater ItemsSource="{x:Bind _keyboardShortcuts}">
<ItemsRepeater.ItemTemplate>
<DataTemplate x:DataType="dmgmt:KeyboardShortcut">
<Border x:Name="bdrKeyboardShortcutBorder" Background="{ThemeResource SystemChromeMediumHighColor}" CornerRadius="10" Margin="10">
<Grid Margin="10" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Execute Code" VerticalAlignment="Center"/>
<StackPanel Grid.Column="1" HorizontalAlignment="Right" VerticalAlignment="Center" Orientation="Horizontal">
<ComboBox Width="150" Margin="10,0,10,0" ItemsSource="{x:Bind Path=dmgmt:KeyboardShortcut.AvailableVirtualKeyModifiers}" SelectionChanged="ComboBoxModifier_SelectionChanged" Loaded="ComboBoxModifier_Loaded"/>
<ComboBox Width="150" Margin="10,0,10,0" ItemsSource="{x:Bind Path=dmgmt:KeyboardShortcut.AvailableVirtualKeyCodes}" SelectionChanged="ComboBoxKey_SelectionChanged" Loaded="ComboBoxKey_Loaded"/>
</StackPanel>
</Grid>
</Border>
</DataTemplate>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
</StackPanel>
</Grid>
引用的C#列表(页面类中的私有属性):
private List<KeyboardShortcut> _keyboardShortcuts { get; set; } = new()
{
PyruxSettings.Keybinds.StartShortcut,
PyruxSettings.Keybinds.StepShortcut,
PyruxSettings.Keybinds.ResetShortcut,
PyruxSettings.Keybinds.PeakGoalLayoutShortcut,
PyruxSettings.Keybinds.SaveShortcut
};
现在我想引用回触发渲染元素的原始列表项,以便为组合框分配默认值。 (即获取组合框所属的快捷方式)。
问题是,根据我的研究,你应该使用 FrameworkElement.DataContext,即 ComboBox.DataContext 或 Border.DataContext。
但是,在 ItemsRepeater 中的所有子元素上,DataContext 只是 null:
如何引用回原始项目/如何使数据上下文实际上具有适当的值?
您可以使用
ItemsRepeater
的ElementPrepared
事件:
private void ItemsRepeater_ElementPrepared(ItemsRepeater sender, ItemsRepeaterElementPreparedEventArgs args)
{
if (args.Element is FrameworkElement element)
{
element.DataContext = _keyboardShortcuts[args.Index];
}
}