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

ibrsph3r  于 2023-02-16  发布在  其他
关注(0)|答案(2)|浏览(145)

我一直在尝试将新生成的图像的source、row和column属性绑定到视图模型中某个对象的某个值上,理想情况下,可以通过绑定传递给eventArgs的对象属性来解决这个问题,有办法吗?
下面是我想做的一个例子:

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

            Enemy.SetBinding(Image.SourceProperty, new Binding("enemyViewModel.Icon"));
            Enemy.SetBinding(Grid.RowProperty, new Binding("enemyViewModel.Row"));
            Enemy.SetBinding(Grid.ColumnProperty, new Binding("enemyViewModel.Column"));

            locationGrid.Children.Add(Enemy);
        }

我一直在考虑使用语法new Binding("property. subproperty"),但是,由于我的"enemyViewModel"对象经常被添加到视图模型的列表中或从列表中删除,所以这个方法似乎不起作用。
我也意识到在代码后面编写代码是不好的做法,但这似乎是从GUI中动态添加和删除图像的唯一方法。
谢谢你的建议。

qni6mghb

qni6mghb1#

你可以写

Enemy.SetBinding(Image.SourceProperty,
    new Binding("Icon")
    {
        Source = enemyViewModel
    });

Enemy.SetBinding(Image.SourceProperty,
    new Binding
    {
        Path = new PropertyPath("Icon"),
        Source = enemyViewModel
    });

但是,您应该考虑使用一个ItemsControl,它使用网格作为其ItemsPanel,并且在其ItemTemplateItemContainerStyle中具有图像和绑定。
在下面的示例中,Enemies将是主视图模型中ObservableCollection<EnemyViewModel>类型的公共属性。

<ItemsControl ItemsSource="{Binding Enemies}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    ... 
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    ...
                </Grid.RowDefinitions>
            </Grid>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="Grid.Column" Value="{Binding Column}"/>
            <Setter Property="Grid.Row" Value="{Binding Row}"/>
        </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Image Source="{Binding Icon}" Stretch="Fill"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

另请参见Data Templating Overview

ee7vknir

ee7vknir2#

您可以在资源字典中定义样式,以将这些设置应用于Image。
这是我制作的一个PoC,我在我的项目中添加了一个Skull.png(用于敌人的图片),并将其设置为资源。
EnemyViewModel有硬编码的值,但当然要设置它们。

public partial class EnemyViewModel : ObservableObject
{
    [ObservableProperty]
    private int row = 2;

    [ObservableProperty]
    private int column = 3;

    [ObservableProperty]
    private BitmapImage icon = new BitmapImage(new Uri("Skull.png", UriKind.Relative));
 }

你可以在你的代码中把datacontext设置为你的enemyviewmodel参数,但是这里我只是在我的主窗口中新建一个,这是非常快速和肮脏的。

public MainWindow()
    {
        InitializeComponent();
        var style = Application.Current.Resources["EnemyStyle"] as Style;
        MyGrid.Children.Add(new Image {Style  = style, DataContext=new EnemyViewModel() });
    }

比起png,我更倾向于使用路径或者画笔和几何图形。我的头骨有点普通,可能不适合路径,因为你只能得到一种颜色的填充和另一种颜色的轮廓。
这可能是这样的:
在我的资源字典里我有。

<Geometry x:Key="Skull">
    M11.2035,16.1L11.103499,18.1C11.5035,18.7 11.9035,19.4 12.0035,20.1 12.203499,19.6 12.403499,19.3 12.703499,18.9 12.803499,18.8 12.803499,18.7 12.603499,18.5 12.403499,18.3 12.203499,18.2 12.0035,17.9 11.803499,17.6 11.803499,17.3 11.7035,17 11.7035,16.7 11.4035,16.4 11.2035,16.1z M10.7035,15.9C10.5035,16.2 10.2035,16.5 10.1035,16.8 9.9035002,17.1 10.0035,17.5 9.8035002,17.8 9.6035002,18.1 9.4035003,18.3 9.2035003,18.5 9.0035004,18.6 9.0035004,18.7 9.1035004,18.9 9.4035003,19.3 9.6035002,19.7 9.8035002,20.1 9.9035002,19.3 10.3035,18.6 10.7035,18z M19.903497,10.3C19.703497,10.3 19.403497,10.4 19.203497,10.5 16.903498,12.1 14.303499,14 11.8035,15.1 15.103498,17.9 21.103497,15.3 20.403497,10.7 20.303497,10.5 20.203497,10.3 19.903497,10.3z M2.0035028,10.3C1.8035026,10.3 1.6035028,10.4 1.6035028,10.7 0.90350294,15.3 6.903501,17.9 10.2035,15.1 7.6035008,14 5.1035016,12.1 2.8035026,10.5 2.4035025,10.4 2.2035027,10.3 2.0035028,10.3z M10.8035,0L11.0035,0C18.203498,0.19999981 25.603496,5 21.403497,14.5 21.403497,14.6 21.303496,14.7 21.203497,14.7 19.503497,17.1 21.703496,19 18.903498,21.2 18.203498,21.2 17.803497,20.9 18.403498,20.1 18.303497,18.5 17.003498,18.9 15.503499,20 15.703498,21.399999 15.303498,22.300001 14.603498,23.5L13.903499,31C13.803499,31.5 13.103499,31.6 12.703499,31.800001 12.703499,28.7 12.903499,26 12.903499,22.899999 14.003499,22.1 13.403499,22.2 12.3035,22.2L12.0035,31.800001C12.103499,31.899999 11.5035,32 10.8035,32 10.7035,29 11.1035,25.6 11.0035,22.6L11.0035,22.5C11.0035,22.2,10.5035,22.2,10.5035,22.399999L10.5035,22.5 10.2035,31.800001C9.9035002,31.899999 9.4035003,31.899999 9.1035004,31.7 9.0035004,28.6 9.1035004,25.399999 9.0035005,22.300001 8.9035005,22.2 8.6035005,22.2 8.5035005,22.300001 8.4035006,25.399999 8.4035006,28.5 8.3035007,31.6 7.8035008,31.399999 7.4035009,31.2 7.2035009,30.7 7.103501,28.2 7.103501,25.6 7.0035011,23.1L7.0035011,22.899999C6.903501,22.5 6.3035014,22.2 6.8035011,20.8 7.103501,20 6.8035011,20.1 6.8035011,19.7 6.4035013,18.7 5.4035015,19.1 3.7035022,20.7L4.6035018,21.2C4.3035021,21.800001 3.7035022,21.399999 3.1035023,20.9 2.9035025,20.7 2.5035024,21.2 2.1035028,21.300001 1.2035027,20.5 0.90350294,19.4 1.4035029,18.6 1.6035028,18.2 1.1035028,17.9 1.2035027,17.5 2.0035028,17.3 2.5035024,17 1.8035026,16.8 0.50350285,13.7 -0.29649639,10.5 0.10350323,6.9999999 0.20350361,2.7 7.103501,0 10.8035,0z
</Geometry>

风格

<Style TargetType="Path" x:Key="EnemyStyle">
    <Setter Property="Fill" Value="Black"/>
    <Setter Property="Stretch" Value="Uniform"/>
    <Setter Property="Data" Value="{Binding Icon}"/>
    <Setter Property="Grid.Row" Value="{Binding Row}"/>
    <Setter Property="Grid.Column" Value="{Binding Column}"/>
</Style>

视图模型

public partial class EnemyViewModel : ObservableObject
{
    [ObservableProperty]
    private int row = 2;

    [ObservableProperty]
    private int column = 3;

    [ObservableProperty]
    private Geometry icon = Application.Current.Resources["Skull"] as Geometry;
 }

相关问题