来自两个来源的 WPF 绑定

WPF binding from two sources

我正在尝试在运行时确定大小的控件中显示一些相册

XAML:

    <Grid>
    <Grid.Resources>
        <DataTemplate x:Key="AlbumsTemplate">
            <Grid>
                <Border Width="{Binding ThumbWidth}" Height="{Binding ThumbHeight}">
                    <Border.Background>
                        <ImageBrush ImageSource="{Binding Cover}"/>
                    </Border.Background>
                </Border>
                <StackPanel>
                    <TextBlock Text="{Binding Artist}" />
                    <TextBlock Text="{Binding Name}" />
                </StackPanel>
            </Grid>
        </DataTemplate>
    </Grid.Resources>

    <Grid.RowDefinitions>
        <RowDefinition />
    </Grid.RowDefinitions>

    <ListBox ItemsSource="{Binding Albums}" ItemTemplate="{DynamicResource AlbumsTemplate}">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel />
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
    </ListBox>
</Grid>

代码隐藏

 public MainWindow()
    {
        InitializeComponent();
        DataContext = new ViewModel();
    }

ViewModel.cs

    class ViewModel
{
    private ObservableCollection<Album> Albums { get; set; }
    public int ThumbWidth { get; set; }
    public int ThumbHeight { get; set; }

    public ViewModel()
    {
        ThumbWidth = 150;
        ThumbHeight = 150;
        Albums = DataSupplier.Instance.GetAlbums();
    }
}

专辑Class

    class Album
{
    public string Name { get; set; }
    public string Artist { get; set; }
    public BitmapImage Cover { get; set; }

    public Album(string name, string artist, BitmapImage cover)
    {
        Name = name;
        Artist = artist;
        Cover = cover;
    }
}

我可以看到所有带有名称、艺术家和封面的专辑,但封面尺寸不正确。

在 DataTemplate 外部的控件中,我可以检索 ThumbWidth 和 ThumbHeight

我错过了什么?

问题是您当前的 DataContext 是 Album 而不是 ViewModel。您只能有 一个 DataContext。

  1. 解决此问题的快速方法是将 ThumbWidthThumbHeight 添加到您的 Album-class。

  2. 更愿意添加一个class AlbumViewModel,其中包含显示相册所需的各种信息(比如:witdh、身高、名字、头衔……)。此外,AlbumViewModel 的列表位于您的 ViewModel 中。这样做是解决 MVVM 问题的常用方法。

  3. 另一种 hacky 方法是,在 xaml:

    中访问父级的数据上下文属性

    {Binding ThumbWidth, ElementName=LayoutRoot}

    有关执行此操作的更多信息here

无需将 height/width 添加到每个 Album,您可以使用 ListBoxDataContext(这是 height/width 的位置)目前是。

您可以使用 FindAncestor 绑定

   <Border Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}, Path=DataContext.ThumbWidth}" 
           Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}, Path=DataContext.ThumbHeight}">