I've been stuck with this problem for days, and as the due date is coming up, I'm really at my wits end.
I have the option to add a new Customer in my application. The Customer is stored in the DB with its ID, Name, and Logo. Logo is just the string of the image file name (like logo.png)
When adding the Customer, I select an Image from my local files to add as the Customer's logo. It shows up nicely in the Add-window.
After confirming the new Cutomer, the CustomerAddView window closes. The Customer is created in the DB, the Logo value in the DB is fine, and in my Windows File Explorer I see it's added.
The list of Customers in the main window is refreshed (CustomerListView). The other Customer's Logo's are working fine. But the new Customer's Logos throws a warning (posted below).
In Visual Studio, even though I refresh and rebuild, the new Logo still doesn't work and it doesn't show up in the Solution Explorer. It's like Visual Studio doesn't acknowedge the existance of the image because it wasn't added via VS itself.
I would like to know why my logo image is there in the File Explorer, in the specified folder, but isn't displayed in the list of Customers as it should.
And I want to know why the images do work when added via Visual Studio's Solution Explorer, but don't work when I add them (to the same folder) via the CustomerAddView(Model).
Screenshot to show the folder structure and to show files added via VS are working and new one isn't. I added the testlogo.png via the CustomerAddView(Model), the other 3 were added right in VS Solution Explorer. As you can see:
- The logo's are all in the same directory.
- Only the logo's added via VS Solution Explorer show in VS Solution Explorer. The new one doesn't.
- The new logo doesn't show in the CustomerListView. The others do.
The warning:
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)'
Thi is the XAML code that displays the Customers and their logo's in a list:
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>
These are the adding screen and its ViewModel: 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
}