You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinUI3中如何获取ItemsRepeater内UI元素的上下文?

WinUI3 ItemsRepeater子元素DataContext为空问题解决

问题场景

我使用WinUI3和C#开发应用,通过ItemsRepeater搭配DataTemplate动态渲染快捷键设置面板,渲染功能正常,但需要获取每个ComboBox所属的原KeyboardShortcut列表项来设置默认值时,发现ItemsRepeater内所有子元素的DataContext均为空,无法关联到对应的列表项。

现有代码

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
};

解决方法

WinUI3中x:Bind默认是编译时绑定,不会自动设置DataContext,这是导致DataContext为空的核心原因,可通过以下两种方式解决:

方式1:显式设置DataTemplate根元素的DataContext

修改DataTemplate的根Border,添加DataContext="{x:Bind}",让模板内所有元素继承对应的KeyboardShortcut实例:

<DataTemplate x:DataType="dmgmt:KeyboardShortcut">
    <Border x:Name="bdrKeyboardShortcutBorder" 
            DataContext="{x:Bind}"
            Background="{ThemeResource SystemChromeMediumHighColor}" 
            CornerRadius="10" 
            Margin="10">
        <!-- 原有内容保持不变 -->
    </Border>
</DataTemplate>

之后在ComboBoxModifier_Loaded或SelectionChanged事件中,即可通过((ComboBox)sender).DataContext获取到对应的KeyboardShortcut对象,进而设置默认选中项。

方式2:直接用x:Bind绑定选中项(推荐)

利用x:Bind直接将ComboBox的SelectedItem绑定到KeyboardShortcut的对应属性,无需手动处理事件,更符合数据驱动逻辑:
假设KeyboardShortcut类包含SelectedModifier和SelectedKey属性,修改ComboBox的XAML代码:

<ComboBox Width="150" 
          Margin="10,0,10,0" 
          ItemsSource="{x:Bind Path=dmgmt:KeyboardShortcut.AvailableVirtualKeyModifiers}"
          SelectedItem="{x:Bind SelectedModifier, Mode=TwoWay}"/>
<ComboBox Width="150" 
          Margin="10,0,10,0" 
          ItemsSource="{x:Bind Path=dmgmt:KeyboardShortcut.AvailableVirtualKeyCodes}"
          SelectedItem="{x:Bind SelectedKey, Mode=TwoWay}"/>

这样ComboBox会自动根据KeyboardShortcut的属性值设置默认选中项,修改后的选中值也会同步回原对象。

补充说明

  • x:Bind默认是OneTime模式,若需要双向同步选中值到数据源,需显式指定Mode=TwoWay。
  • 若KeyboardShortcut类需要支持属性变更通知,需实现INotifyPropertyChanged接口,否则UI不会自动响应属性变化。

内容的提问来源于stack exchange,提问作者LightJack05

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 06:47:14