图像被保存,但不会加载
我可以选择在我的应用程序中添加新的客户。客户使用其ID,名称和徽标存储在数据库中。标志只是图像文件的字符串(如logo.png)图像被保存,但不会加载
标志的添加看起来很好。当我选择一个图像时,它显示在CustomerAddView中。
添加Customer后,CustomerAddView窗口关闭。客户是在数据库中创建的,数据库中的徽标值是正确的。
刷新主窗口中的客户列表(CustomerListView)。其他客户的徽标工作正常。但新客户的徽标(添加了AddView窗口)抛出这样的警告:
System.Windows.Data Warning: 6 : 'DynamicValueConverter' converter failed to convert value '../../Media/Images/Logos/testlogo.png' (type 'String'); fallback value will be used, if available. BindingExpression:Path=Logo; DataItem='Customer_5A59789E69DE0B010CE32D4E23A696EDB09551158A85050E8CA80E51475D369B' (HashCode=45868004); target element is 'Image' (Name=''); target property is 'Source' (type 'ImageSource') IOException:'System.IO.IOException: Kan bron media/images/logos/testlogo.png niet vinden.
bij MS.Internal.AppModel.ResourcePart.GetStreamCore(FileMode mode, FileAccess access)
bij System.IO.Packaging.PackagePart.GetStream(FileMode mode, FileAccess access)
bij System.IO.Packaging.PackWebResponse.CachedResponse.GetResponseStream()
bij System.IO.Packaging.PackWebResponse.GetResponseStream()
bij System.IO.Packaging.PackWebResponse.get_ContentType()
bij System.Windows.Media.Imaging.BitmapDecoder.SetupDecoderFromUriOrStream(Uri uri, Stream stream, BitmapCacheOption cacheOption, Guid& clsId, Boolean& isOriginalWritable, Stream& uriStream, UnmanagedMemoryStream& unmanagedMemoryStream, SafeFileHandle& safeFilehandle)
bij System.Windows.Media.Imaging.BitmapDecoder.CreateFromUriOrStream(Uri baseUri, Uri uri, Stream stream, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption, RequestCachePolicy uriCachePolicy, Boolean insertInDecoderCache)
bij System.Windows.Media.Imaging.BitmapFrame.CreateFromUriOrStream(Uri baseUri, Uri uri, Stream stream, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption, RequestCachePolicy uriCachePolicy)
bij System.Windows.Media.ImageSourceConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
bij MS.Internal.Data.DefaultValueConverter.ConvertHelper(Object o, Type destinationType, DependencyObject targetElement, CultureInfo culture, Boolean isForward)
bij MS.Internal.Data.TargetDefaultValueConverter.Convert(Object o, Type type, Object parameter, CultureInfo culture)
bij MS.Internal.Data.DynamicValueConverter.Convert(Object value, Type targetType, Object parameter, CultureInfo culture)
bij System.Windows.Data.BindingExpression.ConvertHelper(IValueConverter converter, Object value, Type targetType, Object parameter, CultureInfo culture)'
System.Windows.Data Error: 11 : Fallback value 'Default' (type 'String') cannot be converted for use in 'Source' (type 'ImageSource'). BindingExpression:Path=Logo; DataItem='Customer_5A59789E69DE0B010CE32D4E23A696EDB09551158A85050E8CA80E51475D369B' (HashCode=45868004); target element is 'Image' (Name=''); target property is 'Source' (type 'ImageSource') NullReferenceException:'System.NullReferenceException: De objectverwijzing is niet op een exemplaar van een object ingesteld.
bij System.Windows.Media.ImageSourceConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
bij System.Windows.Data.BindingExpressionBase.ConvertValue(Object value, DependencyProperty dp, Exception& e)'
我想知道为什么我的标志形象出现在文件管理器,在指定的文件夹,但不显示在客户列表中,因为它应该。
我想知道为什么当通过Visual Studio的解决方案资源管理器添加图像时工作正常,但是当我通过CustomerAddView(模型)将它们添加到同一文件夹时不起作用。
这里的文件添加一个新的客户: CustomerAddView:
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<TextBlock Name="TBCustomerTitle" FontWeight="Bold">Customer name:</TextBlock>
<TextBlock Grid.Column="1" FontWeight="Bold" Margin="5,0">*</TextBlock>
<TextBox Name="TBCustomerData" Grid.Column="2" Grid.ColumnSpan="2"
Text="{Binding NewCustomer.Name, UpdateSourceTrigger=PropertyChanged}"></TextBox>
<TextBlock Grid.Row="1" FontWeight="Bold">Customer logo:</TextBlock>
<Image Grid.Row="1" Grid.Column="2" MaxHeight="100" MaxWidth="100"
Source="{Binding NewCustomerLogo, UpdateSourceTrigger=PropertyChanged}" />
<Button Grid.Row="1" Grid.Column="3" Content="Choose logo"
Command="{Binding SelectLogoCommand}"/>
<TextBlock Margin="0,10" Grid.Row="2" Grid.ColumnSpan="4">Fields marked with * are required fields.</TextBlock>
<Button Grid.Row="3" Grid.ColumnSpan="4" Margin="0,50,0,0"
Command="{Binding AddConfirmCommand}">Add this customer</Button>
</Grid>
CustomerAddViewModel:
class CustomerAddViewModel : INotifyPropertyChanged
{
private RelayCommand addConfirmCommand;
private RelayCommand selectLogoCommand;
Image customerLogo;
string logoDirectory = "../../Media/Images/Logos/";
DBCustomer dbCustomer = new DBCustomer();
#region Add Customer
public ICommand AddConfirmCommand
{
get { return addConfirmCommand ?? (addConfirmCommand = new RelayCommand(() => AddConfirmCustomer())); }
}
private void AddConfirmCustomer()
{
if(newCustomer.Logo != null)
{
customerLogo.Save(logoDirectory + newCustomer.Logo);
}
else
{
newCustomer.Logo = "Default.png";
}
if (!dbCustomer.Create(newCustomer))
{
return;
}
App.Messenger.NotifyColleagues("AddCustomerDone");
}
#endregion
#region Add logo
public ICommand SelectLogoCommand
{
get { return selectLogoCommand ?? (selectLogoCommand = new RelayCommand(() => SelectLogo())); }
}
private void SelectLogo()
{
OpenFileDialog chooseFile = new OpenFileDialog();
chooseFile.Title = "Select a logo";
chooseFile.Filter = "All supported graphics|*.jpg;*.jpeg;*.png|" +
"JPEG (*.jpg;*.jpeg)|*.jpg;*.jpeg|" +
"Portable Network Graphic (*.png)|*.png";
if(chooseFile.ShowDialog() == DialogResult.OK)
{
Stream reader = File.OpenRead(chooseFile.FileName);
customerLogo = System.Drawing.Image.FromStream((Stream)reader);
MemoryStream finalStream = new MemoryStream();
customerLogo.Save(finalStream, ImageFormat.Png);
// translate to image source
PngBitmapDecoder decoder = new PngBitmapDecoder(finalStream, BitmapCreateOptions.PreservePixelFormat,
BitmapCacheOption.Default);
NewCustomerLogo = decoder.Frames[0];
newCustomer.Logo = newCustomer.Name + ".png";
}
}
private ImageSource newCustomerLogo;
public ImageSource NewCustomerLogo
{
get
{
return newCustomerLogo;
}
set
{
newCustomerLogo = value;
OnPropertyChanged(new PropertyChangedEventArgs("NewCustomerLogo"));
}
}
#endregion
private Customer newCustomer = new Customer();
public Customer NewCustomer
{
get { return newCustomer; }
set { newCustomer = value; OnPropertyChanged(new PropertyChangedEventArgs("NewCustomer")); }
}
#region PropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
PropertyChanged(this, e);
}
#endregion
}
CustomerListView
<ListBox.ItemTemplate>
<!-- This DataTemplate is used for every Customer object in the ListBox.-->
<DataTemplate>
<Border BorderThickness="2" BorderBrush="Black"
Padding="10" Margin="10"
Name="CustomerBorder">
<Grid Name="ItemGrid">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- Logo picture -->
<Image Grid.Row="0" Grid.Column="0" Grid.RowSpan="3" HorizontalAlignment="Center"
Source="{helpers:ConcatString FrontString=../../Media/Images/Logos/, BindTo={Binding Path=Logo, FallbackValue=Default}}"
Height="{Binding ActualHeight, ElementName=ItemGrid}"/>
<!-- Customer name Row-->
<TextBlock Grid.Row="0" Grid.Column="1" Margin="10,0,8,0" FontWeight="Bold"
Name="CustomerTitle">
Customer:
</TextBlock>
<TextBlock Grid.Row="0" Grid.Column="2"
Name="CustomerDataType"
Text="{Binding Path=Name}">
</TextBlock>
<!-- Environment name Row-->
<TextBlock Grid.Row="1" Grid.Column="1" Margin="10,0,8,0" FontWeight="Bold" />
<TextBlock Grid.Row="2" Grid.Column="1" Margin="10,0,8,0" FontWeight="Bold" />
</Grid>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
编辑:
这个截图可能会让我的疑惑更加清晰。 我通过CustomerAddView(Model)添加了testlogo.png,其他3个在VS解决方案资源管理器中正确添加。 正如你所见:
- 标志都在同一个目录。
- 只有通过VS解决方案资源管理器添加的徽标才会显示在VS解决方案资源管理器中。新的没有。
- 新徽标不会显示在CustomerListView中。其他人做。
编辑2:
是它可能是更好的主意,将图像保存到数据库中,而不是保存的文件名作为数据库中的字符串?
MSDN说:
访问存储在应用程序包中的文件,但是从代码 那里没有推断root权限,指定MS-APPX: 方案。
var uri = new System.Uri("ms-appx:///images/logo.png");
我试图在XAML中使用这个应该得到标识的标签,正如我在OP中发布的那样。我将图像的Source属性更改为Source =“{helpers:ConcatString FrontString = ms-appx:/// Media/Images/Logos /,BindTo = {Binding Path = Logo,FallbackValue = Default}}”'不过,它会抛出一个异常,大部分与OP中的相同,但也是一个新的异常,它说:'NotSupportedException:'System.NotSupportedException:URI前缀不被识别# 当我刚刚放入Source =“ms-appx:/ //Media/Images/Logos/Vodafone.png“(我通过VS添加的图像,这是工作b4)它没有显示,没有img,也没有例外。 – Kailayla
该MSDN文章是关于Window Store/UWP应用程序,而问题是关于WPF。 ms-appx:// URI在WPF中不起作用。 – Clemens
结合路径当然应该是'NewCustomer.Logo'不'NewCustomerLogo'。除此之外,你不需要在任何单向绑定上设置'UpdateSourceTrigger = PropertyChanged'。这是多余的,没有效果。 – Clemens
CustomerAddView窗口中的绑定工作正常,正如我已经说过的。这是CustomerListView(我刚刚在原始文章中添加),通过CustomerAddView添加时没有显示它,但是当我直接将它们添加到Visual Studio中时,它们确实有效。 – Kailayla
你已经在输出中看到了这个:'System.IO.IOException:Kan bron media/images/logos/testlogo.png niet vinden'?这显然不是'../../ media/images/logos/testlogo.png'。 – Clemens