如何在ItemsRepeater的ItemTemplate中绑定ViewModel?
解决方案:ItemsRepeater模板内绑定ViewModel命令
在ItemsRepeater的ItemTemplate中,每个项的DataContext默认是ItemsSource里的单个数据对象(你的场景里就是Channel实例),而非页面的ViewModel,所以直接用{Binding}绑定ViewModel的命令会失效,以下是几种可行方案:
方案一:通过RelativeSource绑定父容器的DataContext
利用RelativeSource找到页面/用户控件的DataContext(即ViewModel),直接绑定对应命令:
<Button Grid.Row="2" Grid.ColumnSpan="2" HorizontalAlignment="Center" Content="Kanal Entfernen" Command="{Binding DataContext.RemoveChannelCommand, RelativeSource={RelativeSource AncestorType=Page}}" CommandParameter="{Binding}" />
AncestorType根据实际父容器类型调整(比如是UserControl就写UserControl)CommandParameter="{Binding}"可以把当前Channel对象传给ViewModel的命令,方便后续移除操作
方案二:使用x:Bind直接指定ViewModel
如果页面的ViewModel是公开的属性(比如页面类里有public MainViewModel ViewModel { get; }),可以用x:Bind直接绑定,无需依赖DataContext:
<DataTemplate x:Name="ChannelTemplate"> <!-- 其他元素 --> <Button Grid.Row="2" Grid.ColumnSpan="2" HorizontalAlignment="Center" Content="Kanal Entfernen" Command="{x:Bind ViewModel.RemoveChannelCommand, Mode=OneWay}" CommandParameter="{Binding}" /> </DataTemplate>
注意:这种方式要求ViewModel是页面的公共属性,且x:Bind默认是编译时绑定,类型检查更严格。
方案三:将命令封装到数据项模型中(推荐MVVM模式)
给Channel类添加命令属性,在ViewModel中初始化该命令并关联到移除逻辑:
// Channel类 public class Channel { public int ChannelId { get; set; } public ICommand RemoveCommand { get; set; } } // ViewModel中初始化项 public ObservableCollection<Channel> ChannelSource { get; } = new(); public void LoadChannels() { var channels = GetChannelsFromSomewhere(); foreach(var channel in channels) { channel.RemoveCommand = new RelayCommand(() => ChannelSource.Remove(channel)); ChannelSource.Add(channel); } }
然后在XAML中直接绑定:
<Button Grid.Row="2" Grid.ColumnSpan="2" HorizontalAlignment="Center" Content="Kanal Entfernen" Command="{Binding RemoveCommand}" />
这种方式更符合MVVM的单一职责原则,每个数据项自己管理相关命令逻辑。
内容的提问来源于stack exchange,提问作者jack
相关产品推荐
相关产品推荐

