图像会被保存,但不会加载

时间:2016-04-15 12:16:47

标签: c# wpf image xaml mvvm

我可以选择在我的应用程序中添加新客户。客户存储在DB中,其ID,名称和徽标。徽标只是图像文件的字符串(如logo.png)

添加徽标似乎很好。当我选择一个图像时,它会显示在CustomerAddView中。

添加Customer后,将关闭CustomerAddView窗口。客户是在DB中创建的,DB中的Logo值很好 将刷新主窗口中的Customers列表(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>

修改
这个截图可能会让我感到困惑。 The problem 我通过CustomerAddView(Model)添加了testlogo.png,另外3个在VS Solution Explorer中添加。 如你所见:

  • 徽标都在同一目录中。
  • VS解决方案资源管理器中仅显示通过VS解决方案资源管理器添加的徽标。新的没有。
  • 新徽标未显示在CustomerListView中。其他人呢。

编辑2:
是否可以将图像保存到数据库而不是将文件名保存为数据库中的字符串?

1 个答案:

答案 0 :(得分:0)

MSDN说:

  

访问存储在应用程序包中的文件,但是来自代码   如果没有推断的root权限,请指定ms-appx:   方案

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