Dav*_*ave 8 c# wpf listview image mvvm
我试图在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;
}
}
Run Code Online (Sandbox Code Playgroud)
在我使用的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>
Run Code Online (Sandbox Code Playgroud)
这个想法被无耻地从以下内容中偷走了: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>
Run Code Online (Sandbox Code Playgroud)
这段代码肯定会通过数据绑定 - 我的断点在程序开始时以及每当项目被添加到集合时被点击.但是没有显示图像.不要用更多不起作用的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;
}
Run Code Online (Sandbox Code Playgroud)
我使用了他建议的确切XAML.它几乎可以工作.我说"差不多"因为我注意到奇怪的行为,有时一张卡会显示,有时不会(我从来没有2张卡).所有从文件和绑定中取出的卡片似乎都在工作,我追踪到了我认为最后剩下的bug(也就是BIZARRE)的关键.如果在调试器中,我检查结果,并在调试器中进一步打开结果[0],我会显示该卡!我实际上必须打开[0](你看到有关高度,宽度等的信息)才能使用.此外,如果我打开[1],我会显示该卡.为什么打开调试器信息有什么影响?对于那些可能会问的人,如果你在调试器中打开这两张卡会发生什么......那是行不通的.我得到一个操作超时异常.我会说,也许我的图像文件很大.10Kbytes到30Kbytes.那是问题吗?我猜不是,这是读取图像或装订时的一个微妙问题.到底是怎么回事?谢谢,戴夫
Cle*_*ens 10
首先,您不应在ViewModel中使用Image控件.您已在视图的DateTemplate中拥有Image控件.您想绑定Source此Image conntrol 的属性,并且此绑定的source属性不能是另一个Image.
相反,您的ViewModel将使用ImageSource(或类似派生类BitmapImage)作为图像类型,如下所示:
public ObservableCollection<ImageSource> PlayerCardImages
{
get
{
var results = new ObservableCollection<ImageSource>();
foreach (var card in PlayerCards)
{
results.Add(new BitmapImage(new Uri(card.ImageUrl)));
}
return results;
}
}
Run Code Online (Sandbox Code Playgroud)
或者只是图像URI或路径,因为自动转换string为ImageSource内置到WPF中:
public ObservableCollection<string> PlayerCardImages
{
get
{
var results = new ObservableCollection<string>();
foreach (var card in PlayerCards)
{
results.Add(card.ImageUrl);
}
return results;
}
}
Run Code Online (Sandbox Code Playgroud)
您现在将Listbox的ItemsSource属性绑定到PlayerCardGames集合,并在DataTemplate中直接绑定到集合项.必须将ListView的DataContext设置为定义PlayerCardGames属性的对象的实例.
<ListView ItemsSource="{Binding PlayerCardGames}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<Image Source="{Binding}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Run Code Online (Sandbox Code Playgroud)
更新:由于加载图像文件似乎有问题,您可以尝试以下方法.它同步加载图像,您可以使用调试器.
public static ImageSource LoadImage(string fileName)
{
var image = new BitmapImage();
using (var stream = new FileStream(fileName, FileMode.Open))
{
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.StreamSource = stream;
image.EndInit();
}
return image;
}
Run Code Online (Sandbox Code Playgroud)
您可以在PlayerCardGames属性getter中使用此方法,如下所示:
foreach (var card in PlayerCards)
{
results.Add(LoadImage(@"Images\\" + GetCardFileName(card)));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
29166 次 |
| 最近记录: |