来自两个来源的 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。
解决此问题的快速方法是将 ThumbWidth
和 ThumbHeight
添加到您的 Album
-class。
我更愿意添加一个class AlbumViewModel
,其中包含显示相册所需的各种信息(比如:witdh、身高、名字、头衔……)。此外,AlbumViewModel
的列表位于您的 ViewModel
中。这样做是解决 MVVM 问题的常用方法。
另一种 hacky 方法是,在 xaml:
中访问父级的数据上下文属性
{Binding ThumbWidth, ElementName=LayoutRoot}
有关执行此操作的更多信息here。
无需将 height/width 添加到每个 Album
,您可以使用 ListBox
的 DataContext
(这是 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}">
我正在尝试在运行时确定大小的控件中显示一些相册
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。
解决此问题的快速方法是将
ThumbWidth
和ThumbHeight
添加到您的Album
-class。我更愿意添加一个class
AlbumViewModel
,其中包含显示相册所需的各种信息(比如:witdh、身高、名字、头衔……)。此外,AlbumViewModel
的列表位于您的ViewModel
中。这样做是解决 MVVM 问题的常用方法。另一种 hacky 方法是,在 xaml:
中访问父级的数据上下文属性{Binding ThumbWidth, ElementName=LayoutRoot}
有关执行此操作的更多信息here。
无需将 height/width 添加到每个 Album
,您可以使用 ListBox
的 DataContext
(这是 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}">