2016-04-15 24 views
2

Ich habe die Option, einen neuen Kunden in meiner Anwendung hinzuzufügen. Der Kunde wird mit seiner ID, seinem Namen und seinem Logo in der Datenbank gespeichert. Logo ist nur die Zeichenfolge der Bilddatei (wie logo.png)Bild wird gespeichert, aber wird nicht geladen

Das Hinzufügen des Logos scheint in Ordnung. Wenn ich ein Bild auswähle, wird es in der CustomerAddView angezeigt.

Nach dem Hinzufügen des Kunden wird das Fenster CustomerAddView geschlossen. Der Kunde wird in der DB angelegt, der Logo-Wert im DB ist in Ordnung.
Die Liste der Kunden im Hauptfenster wird aktualisiert (CustomerListView). Die Logos des anderen Kunden funktionieren einwandfrei. Aber die Logos der neuen Kunden (hinzugefügt mit dem AddView Fenster) diese Warnung werfen:

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)' 

Ich möchte, warum Bild mein Logo wissen, ist es im Datei-Explorer, in den angegebenen Ordner, wird aber nicht angezeigt in der Liste der Kunden, wie es sein sollte.
Und ich möchte wissen, warum die Bilder funktionieren, wenn sie über den Projektmappen-Explorer von Visual Studio hinzugefügt werden, funktionieren aber nicht, wenn ich sie über das CustomerAddView (Model) in den gleichen Ordner hinzufüge.

Hier die Dateien für das Hinzufügen eines neuen Kunden: 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> 

EDIT:
Dieser Screenshot könnte etwas Licht auf meine Verwirrung werfen. The problem Ich habe die testlogo.png über die CustomerAddView (Model) hinzugefügt, die anderen 3 wurden direkt in VS Solution Explorer hinzugefügt. Wie Sie sehen können:

  • Die Logos befinden sich alle im selben Verzeichnis.
  • Nur die über den VS Solution Explorer hinzugefügten Logos werden im VS Solution Explorer angezeigt. Das Neue nicht.
  • Das neue Logo wird nicht in der CustomerListView angezeigt. Die anderen tun es.

EDIT 2:
Ist es vielleicht eine bessere Idee, um das Bild in die Datenbank statt Speichern die Dateinamen als String in der Datenbank zu speichern?

+0

Der Bindungspfad sollte sicher sein 'NewCustomer.Logo' nicht' NewCustomerLogo'. Außerdem müssen Sie 'UpdateSourceTrigger = PropertyChanged' nicht für eine unidirektionale Bindung festlegen.Es ist überflüssig und hat keine Wirkung. – Clemens

+0

Die Bindung im Fenster CustomerAddView funktioniert ordnungsgemäß, wie ich bereits erwähnt habe. Es ist die CustomerListView (die ich gerade im ursprünglichen Post hinzugefügt habe), die es nicht zeigt, wenn es über die CustomerAddView hinzugefügt wird, aber wenn ich sie direkt in Visual Studio hinzufüge, funktionieren sie. – Kailayla

+0

Und Sie haben dies in der Ausgabe gesehen: 'System.IO.IOException: Kan bron Medien/images/logos/testlogo.png niet vinden'? Was anscheinend nicht "../../ media/images/logos/testlogo.png" ist. – Clemens

Antwort

0

MSDN sagt:

Dateien innerhalb des Anwendungspakets gespeichert zuzugreifen, aber von Code , wo es keine abgeleitete Rootberechtigung ist, geben Sie die ms-appx: Schema.

var uri = new System.Uri("ms-appx:///images/logo.png"); 
+0

Ich habe versucht, dies in der XAML, die das Logo bekommen sollte, wie in meinem OP veröffentlicht. Ich habe die Source-Eigenschaft des Bildes in 'Source =" geändert {helpers: ConcatString FrontString = ms-appx: /// Medien/Images/Logos /, BindTo = {Bindungspfad = Logo, FallbackValue = Standard}} " es löst eine Ausnahme aus, meistens die gleiche wie im OP, aber auch eine neue, es heißt: 'NotSupportedException: 'System.NotSupportedException: Das URI-Präfix wird nicht erkannt.' Wenn ich einfach Source =" ms-appx:///Media/Images/Logos/Vodafone.png "(ein Bild, das ich VS hinzugefügt habe und das funktionierte b4) es zeigt nichts, keine IMG und keine Ausnahme. – Kailayla

+1

Dieser MSDN Artikel ist über Windows Store/UWP-Apps, während die Frage über WPF ist. Ein 'ms-appx: //' URI wird in WPF nicht funktionieren. – Clemens

Verwandte Themen