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

如何以编程方式绑定传入的EnemyViewModel对象的属性?

解决动态Image控件绑定ViewModel属性的问题

一、修正当前代码的绑定错误

你现在的绑定写法存在问题,new Binding("enemyViewModel.Icon")这类路径是无效的——绑定默认会从控件的DataContext中查找对应属性,而非直接引用方法内的局部变量。可以用两种方式修正:

方式1:设置Image的DataContext为传入的EnemyViewModel

private void OnNewEnemy(EnemyViewModel enemyViewModel)
{
    Image enemyImage = new Image()
    {
        Stretch = Stretch.Fill,
        DataContext = enemyViewModel // 将DataContext指向传入的ViewModel对象
    };

    // 绑定路径直接写属性名即可
    enemyImage.SetBinding(Image.SourceProperty, new Binding(nameof(EnemyViewModel.Icon)));
    enemyImage.SetBinding(Grid.RowProperty, new Binding(nameof(EnemyViewModel.Row)));
    enemyImage.SetBinding(Grid.ColumnProperty, new Binding(nameof(EnemyViewModel.Column)));

    locationGrid.Children.Add(enemyImage);
}

方式2:直接在Binding中指定Source为EnemyViewModel

private void OnNewEnemy(EnemyViewModel enemyViewModel)
{
    Image enemyImage = new Image()
    {
        Stretch = Stretch.Fill
    };

    enemyImage.SetBinding(Image.SourceProperty, new Binding(nameof(EnemyViewModel.Icon)) { Source = enemyViewModel });
    enemyImage.SetBinding(Grid.RowProperty, new Binding(nameof(EnemyViewModel.Row)) { Source = enemyViewModel });
    enemyImage.SetBinding(Grid.ColumnProperty, new Binding(nameof(EnemyViewModel.Column)) { Source = enemyViewModel });

    locationGrid.Children.Add(enemyImage);
}

二、更优的MVVM方案:用ItemsControl自动管理动态元素

你提到“代码后置是动态增删的唯一方式”其实是误解,使用ItemsControl绑定ViewModel中的敌人列表才是符合MVVM规范的做法,无需手动操作Grid的Children,增删列表元素时UI会自动同步:

1. ViewModel中维护可观察集合

确保主ViewModel里有一个可观察集合:

public ObservableCollection<EnemyViewModel> Enemies { get; } = new ObservableCollection<EnemyViewModel>();

后续添加/移除敌人时,直接对这个集合操作即可,无需触发事件调用代码后置。

2. XAML中配置ItemsControl

在XAML里定义ItemsControl,指定用Grid作为布局容器,同时绑定Row、Column和Image的Source:

<ItemsControl ItemsSource="{Binding Enemies}">
    <!-- 指定ItemsControl使用Grid作为布局面板 -->
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid x:Name="locationGrid" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <!-- 设置每个Item容器的Grid.Row和Grid.Column -->
    <ItemsControl.ItemContainerStyle>
        <Style>
            <Setter Property="Grid.Row" Value="{Binding Row}" />
            <Setter Property="Grid.Column" Value="{Binding Column}" />
        </Style>
    </ItemsControl.ItemContainerStyle>
    <!-- 定义每个敌人的UI模板 -->
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Image Stretch="Fill" Source="{Binding Icon}" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

这样一来,当你在ViewModel中对Enemies集合执行Add/Remove操作时,UI会自动创建/销毁对应的Image控件,既符合MVVM规范,也避免了手动操作UI带来的维护问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 14:50:22