我试图在 ListView 中显示一些图像并且没有成功。我正在使用 WPF MVVM,而 ListView 是简单地显示西装和排名数据的保留。(请参阅我以前的帖子:WPF 中的 MVVM - 如何提醒 ViewModel 模型发生变化......或者我应该吗?如果你有兴趣!)也就是说,我可以使用 ListView 以外的东西(如果这是建议的话)但我仍然想知道如何用 ListView 来做,假设它是可行的。我在 ViewModel 中绑定的属性是:
public ObservableCollection<Image> PlayerCardImages{
get{
ObservableCollection<Image> results = new ObservableCollection<Image>();
foreach (CardModel card in PlayerCards)
{
Image img = new Image();
BitmapImage bi3 = new BitmapImage();
bi3.BeginInit();
// TODO: Pick card based on suit/rank. Just get 1 image working now
bi3.UriSource = new Uri("diamond-1.png", UriKind.Relative);
bi3.EndInit();
img.Stretch = Stretch.Fill;
img.Source = bi3;
results.Add(img);
}
return results;
}
}
在我使用的XAML代码中:
<Window.Resources>
<DataTemplate x:Key="ImageCell">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding PlayerCardImages}" Width="200" Height="200" Stretch="Fill" ToolTip="Add tooltip"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<StackPanel Orientation="Vertical">
<Label Content="Player Cards"/>
<ListView Name="lvwTitles" ItemsSource="{Binding}"
IsSynchronizedWithCurrentItem="True"
SelectionMode="Single" ItemTemplate="{StaticResource ImageCell}" Height="59">
</ListView>
</StackPanel>
这个想法被无耻地窃取了:WPF - 将图像水平绑定到 ListView 但是,它甚至没有出现数据绑定,正如我在 PlayerCardImages 中的断点没有被命中所证明的那样。
我还尝试了以下 XAML,但运气更好:
<StackPanel Orientation="Vertical">
<Label Content="Player Cards"/>
<ListView
AlternationCount="2"
DataContext="{StaticResource PlayerCardsGroups }"
ItemsSource="{Binding}"
>
<ListView.GroupStyle>
<StaticResourceExtension
ResourceKey="CardGroupStyle"
/>
</ListView.GroupStyle>
<ListView.View>
<GridView>
<GridViewColumn>
<Image Height="50" Width="40"></Image>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
<Window.Resources>
<CollectionViewSource x:Key="PlayerCardsGroups"
Source="{Binding Path=PlayerCardImages}">
</CollectionViewSource>
<GroupStyle x:Key="CardGroupStyle">
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock
x:Name="txt"
Background="{StaticResource Brush_HeaderBackground}"
FontWeight="Bold"
Foreground="White"
Margin="1"
Padding="4,2,0,2"
Text="Cards"
/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
<Style x:Key="CardItemStyle" TargetType="{x:Type ListViewItem}">
<!--
Stretch the content of each cell so that we can
right-align text in the Total Sales column.
-->
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<!--
Bind the IsSelected property of a ListViewItem to the
IsSelected property of a CustomerViewModel object.
-->
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="ItemsControl.AlternationIndex" Value="1" />
<Condition Property="IsSelected" Value="False" />
<Condition Property="IsMouseOver" Value="False" />
</MultiTrigger.Conditions>
<Setter Property="Background" Value="#EEEEEEEE" />
</MultiTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
这段代码肯定会通过数据绑定——我的断点在程序开始时以及每当项目被添加到集合时被命中。但没有显示图像。与其用更多不起作用的 XAML 来折磨你,也许我可以请人指点我一些代码/示例/文档,这些代码/示例/文档显示如何将图像列表绑定到 ListView(或另一个控件,如果你真的觉得 ListView 是不当)。请注意,我的收藏是我绑定的东西。我注意到在许多示例中,它们都绑定到子属性。即他们可能有一个专辑的集合,并且对于每个专辑,他们绑定到它的属性图像(请参阅:在 WPF ListView 中将项目显示为图像)。
任何想法或帮助将不胜感激。
-戴夫
附加信息。
根据 Clemens 的建议,我现在有了 PlayerCardImages 的以下代码:
public ObservableCollection<ImageSource> PlayerCardImages
{
get
{
var results = new ObservableCollection<ImageSource>();
//if (PlayerCards.Count == 0)
// return results;
//else
//{
// results.Add(new BitmapImage(new Uri(@"Images\\" + "diamond-1.png", UriKind.Relative)));
//}
foreach (var card in PlayerCards)
{
results.Add(new BitmapImage(new Uri(@"Images\\" + GetCardFileName(card), UriKind.Relative)));
}
return results;
}
我使用了他建议的确切 XAML。它几乎可以工作。我说“几乎”是因为我注意到奇怪的行为,有时会显示 1 张卡,有时不会显示(我从未得到 2 张卡)。所有从文件和绑定中获取卡片似乎都在工作,我找到了我认为是最后一个错误的关键(这很奇怪)。如果在调试器中检查结果,并在调试器中进一步打开 results[0],我会显示该卡!实际上,我必须打开 [0](您会看到有关高度、宽度等的信息)才能使其正常工作。此外,如果我打开 [1],则会显示该卡。为什么打开调试器信息会有任何影响?对于那些可能会问的人,如果您在调试器中打开两张卡会发生什么......这是行不通的。我得到一个操作超时异常。我会说也许我的图像文件很大。10 KB 到 30 KB。那是问题吗?我猜不是,这是阅读图像或装订的一个微妙问题。到底是怎么回事?谢谢,戴夫