如何使用从数据库派生的相对文件路径将 WPF 图像元素绑定到本地硬盘驱动器上的 PNG?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17267021/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I bind a WPF Image element to a PNG on the local hard drive using a relative filepath derived from a DB?
提问by Timothy John Laird
I've got a folder on the local hard drive with several images in it. The image names/paths are stored in a local SQLCE database. In a WPF application I'm trying to bind those images to an Image element (which eventually goes into a listbox). I've got the application to run and compile and the listbox shows up but there is no image where it is supposed to be.
我在本地硬盘上有一个文件夹,里面有几张图片。图像名称/路径存储在本地 SQLCE 数据库中。在 WPF 应用程序中,我试图将这些图像绑定到一个 Image 元素(最终进入一个列表框)。我已经让应用程序运行和编译,列表框出现了,但没有图像应该在那里。
This is the XAML that defines the data template that the listbox uses...
这是定义列表框使用的数据模板的 XAML...
<Window.Resources>
<DataTemplate x:Key="assetLBTemplate">
<StackPanel Orientation="Horizontal">
<Image Height="32" Width="32" Source="{Binding imageFileName}" />
<TextBlock Text="{Binding imageFileName}" />
<TextBlock Text="{Binding assetName}" />
</StackPanel>
</DataTemplate>
</Window.Resources>
The XAML for the listbox...
列表框的 XAML...
<ListBox x:Name="lbAssetsLiquid"
ItemsSource="{Binding Tables[0]}"
ItemTemplate="{StaticResource assetLBTemplate}"
BorderThickness="1, 1, 1, 1" Grid.Column="0" Grid.Row="1" />
The code that I run on Window_Loaded:
我在 Window_Loaded 上运行的代码:
private void BindLiquidAssetsListBoxData()
{
SqlCeConnection connection;
SqlCeCommand command;
string sql = "SELECT tblLiquidAssets.assetName, tblLiquidAssets.assetQuantity, tblLiquidAssets.assetValueGP, tblLiquidAssets.assetDescription, tblImages.imageFileName FROM tblLiquidAssets INNER JOIN tblImages ON tblLiquidAssets.assetImageIndex=tblImages.imageID;";
string connectionString = "Data Source=sharecalc_db.sdf;Persist Security Info=False;";
DataSet dtSet = new DataSet();
try
{
using (connection = new SqlCeConnection(connectionString))
{
command = new SqlCeCommand(sql, connection);
SqlCeDataAdapter adapter = new SqlCeDataAdapter();
connection.Open();
adapter.SelectCommand = command;
adapter.Fill(dtSet, "tblLiquidAssets");
lbAssetsLiquid.DataContext = dtSet;
connection.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
The result from the SQL Query is...
SQL 查询的结果是...


Again...the program loads with the listbox but no images get loaded.
再次...程序加载列表框,但没有加载图像。
I get this in the output window, which makes me I think I am missing something important here...
我在输出窗口中得到了这个,这让我觉得我在这里遗漏了一些重要的东西......
converter failed to convert value 'gold64.png' (type 'String')
转换器无法转换值“gold64.png”(类型“字符串”)
When I add the images to the project itself in Solution Explorer it seems to work (the images appear where they are supposed to be)...but it does not work otherwise. Can someone shove me in the right direction?
当我在解决方案资源管理器中将图像添加到项目本身时,它似乎可以工作(图像出现在它们应该出现的位置)......但它不工作。有人可以将我推向正确的方向吗?
采纳答案by Athari
You need to use custom value converter to convert strings to images if you want to load files from the file system. Image.Source, when a string is passed, expects a file name from resources. You can find implementation of a such converter here: Display an image in WPF without holding the file open.
如果要从文件系统加载文件,则需要使用自定义值转换器将字符串转换为图像。Image.Source, 传递字符串时,需要来自资源的文件名。您可以在此处找到此类转换器的实现:在 WPF 中显示图像而无需打开文件。
回答by Timothy John Laird
Thank you Athari, you got me on the right path!
谢谢Athari,你让我走上了正确的道路!
Revised chunk of XAML...
修改了 XAML 的块...
<Window x:Class="pf_sharecalc.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Share Calculator" WindowStyle="ThreeDBorderWindow" Loaded="Window_Loaded"
xmlns:local="clr-namespace:pf_sharecalc">
<Window.Resources>
<local:PathToImageConverter x:Key="PathToIMageConverter"/>
<DataTemplate x:Key="assetLBTemplate">
<StackPanel Orientation="Horizontal">
<Image Height="32" Width="32" Source="{Binding imageFileName, Converter={StaticResource PathToIMageConverter}}" />
<TextBlock Text="{Binding imageFileName}" />
<TextBlock Text="{Binding assetName}" />
</StackPanel>
</DataTemplate>
</Window.Resources>
And I added this code...
我添加了这段代码......
public class PathToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string path = value as string;
if (path != null)
{
BitmapImage image = new BitmapImage();
using (FileStream stream = File.OpenRead(path))
{
image.BeginInit();
image.StreamSource = stream;
image.CacheOption = BitmapCacheOption.OnLoad;
image.EndInit(); // load the image from the stream
} // close the stream
return image;
}
else
return null;
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
I'll have to do some fine tuning to get exactly what I want, but I've passed the road-block.
我必须做一些微调才能得到我想要的东西,但我已经通过了障碍。

