WPF MVVM C# Image updating

2019-09-02 14:04发布

Can please any one show me some example on web or explain Image updating in WPF MVVM C#.

My XAML code:

<Image Source="{Binding PicturePath}" VerticalAlignment="Center" Margin="0,0,10,0"/>

C# code

private string _picturepath;
public string PicturePath
{
    get { return _picturepath; }
    set
    {
        _picturepath = value;
         NotifyPropertyChanged("PicturePath");
    }
}

PicturePath = IconPath + @"\Logo.png";

And when picture change, I update PicturePath, but Image in program stay the same. What I need more?

标签: c# wpf image mvvm
3条回答
Luminary・发光体
2楼-- · 2019-09-02 14:51

You need to implement the interface INotifyPropertyChanged, add this code, then call OnPropertyChanged() from the setter of PicturePath.

void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
    PropertyChangedEventHandler handler = PropertyChanged;
    if (handler != null)
    {
        handler(this, new PropertyChangedEventArgs(propertyName));
    }
}
查看更多
手持菜刀,她持情操
3楼-- · 2019-09-02 15:00

Here's what I ended up with in my project (and I've got to say it took quite a while testing different things that seemed to almost work). You can see the commented code which was also not working 100% don't remember why)

So all my Images from app assets that are starting with "ms-appx:" I use with setting the source without loading to stream, because these never change (default images etc)

The other images that are created or changed by the user I had to reload and set the source with the result of the file read (otherwise when they were changed sometimes they were not updating)

So basically I use this converter on almost all of the places that I use images that can change (without changing their name).

define your converter:

<converters:ImageConverter x:Key="ImageConverter" /> 

And then use like this

<Image Source="{Binding PictureFilename, Converter={StaticResource ImageConverter}}"
       HorizontalAlignment="Center"
       VerticalAlignment="Center"/>

(Another workaround is to name your images differently and then when you update the source path it works fine.)

public class ImageConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        try
        {
            var CapturedImage = new BitmapImage();
            CapturedImage.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
            if (((string)value).StartsWith("ms-appx:"))
            {
                CapturedImage.UriSource = new Uri((string)value, UriKind.RelativeOrAbsolute);
                return CapturedImage;

            }
            var file = (StorageFile.GetFileFromPathAsync(new Uri((string)value, UriKind.RelativeOrAbsolute).LocalPath).AsTask().Result);
            using (IRandomAccessStream fileStream = file.OpenAsync(FileAccessMode.Read).AsTask().Result)
            {
                CapturedImage.SetSource(fileStream);
                return CapturedImage;

            }
        }
        catch (Exception e)
        {
            Logger.Error("Exception in the image converter!", e);
            return new BitmapImage();
        }

        //BitmapImage img = null;
        //if (value is string)
        //{
        //    img = new BitmapImage();
        //    img.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
        //    img.UriSource = new Uri((string)value, UriKind.RelativeOrAbsolute);
        //}

        //if (value is Uri)
        //{
        //    img = new BitmapImage();
        //    img.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
        //    img = new BitmapImage((Uri)value);
        //}

        //return img;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}
查看更多
够拽才男人
4楼-- · 2019-09-02 15:09

So now I made stand alone procjet only for picture binding

ImageConverter code:

public class ImageConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo language)
    {
        try
        {
            return new BitmapImage(new Uri((string)value));
        }
        catch
        {
            return new BitmapImage();
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo language)
    {
        throw new NotImplementedException();
    }
}

MainWindowViewModel:

public class MainWindowViewModel : ViewModelBase
{
    public MainWindowViewModel()
    {
        Changetopicone = new RelayCommand(param => piconevoid());
        Changetopictwo = new RelayCommand(param => pictwovoid());
        LogoSourcePath = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
    }

    private void piconevoid()
    {
        PicturePath = LogoSourcePath + @"\pic1.png";
    }

    private void pictwovoid()
    {
        PicturePath = LogoSourcePath + @"\pic2.png";
    }

    public string LogoSourcePath { get; set; }

    private string _picturepath;
    public string PicturePath
    {
        get { return _picturepath; }
        set
        {
            _picturepath = value;
            NotifyPropertyChanged("PicturePath");
        }
    }

    public ICommand Changetopicone
    {
        get;
        set;
    }

    public ICommand Changetopictwo
    {
        get;
        set;
    }
}

MainWindow:

<StackPanel>
        <Button Command="{Binding Changetopicone}" Content="Changetopicone"/>
        <Button Command="{Binding Changetopictwo}" Content="Changetopictwo"/>
        <Image Source="{Binding PicturePath, Converter={StaticResource ImgCon}}" VerticalAlignment="Center" Width="200" Height="200"/>
    </StackPanel>

In my program I have some problem, so I made this standalone project to be sure that works.

Thanks for all the help!

查看更多
登录 后发表回答