【问题标题】:WPF MVVM C# Image updatingWPF MVVM C#​​ 图像更新
【发布时间】:2016-01-29 22:01:23
【问题描述】:

请任何人在网上给我看一些例子或解释 WPF MVVM C#​​ 中的图像更新。

我的 XAML 代码:

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

C#代码

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

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

当图片改变时,我更新PicturePath,但程序中的图片保持不变。我还需要什么?

【问题讨论】:

  • 可能,您必须实现 INotifyPropertyChanged 以通知视图有关更改。你使用什么 MVVM 模式?
  • 你实现了 INotifyPropertyChanged 吗?
  • NotifyPropertyChanged 你认为?是的,我有它.. 还是你想别的?
  • 您覆盖了Logo.png 文件并想重新加载它?
  • 您正在尝试在路径的字符串上实现INotifyPropertyChanged。 INPC 将“更新”的唯一方法是更改​​路径字符串。覆盖驱动器上的文件不会触发事件。如果您想在新图像覆盖时更新图像,您需要实现 FileSystemWatcher

标签: c# wpf image xaml mvvm


【解决方案1】:

你需要实现接口INotifyPropertyChanged,添加这段代码,然后从PicturePath的setter中调用OnPropertyChanged()。

void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
    PropertyChangedEventHandler handler = PropertyChanged;
    if (handler != null)
    {
        handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

【讨论】:

  • OP 正在讨论覆盖驱动器上的图像。在这种情况下,在路径上的字符串上实现 INPC 不会触发他所要求的。
【解决方案2】:

这是我在项目中最终得到的结果(我不得不说,我花了很长时间测试似乎几乎可以工作的不同事物)。你可以看到注释代码也不能工作 100% 不记得为什么)

所以我所有以“ms-appx:”开头的应用程序资产中的图像我都使用设置源而不加载到流,因为这些永远不会改变(默认图像等)

由用户创建或更改的其他图像我必须重新加载并使用文件读取的结果设置源(否则当它们被更改时有时它们不会更新)

所以基本上我在几乎所有我使用可以更改(不更改名称)图像的地方使用这个转换器。

定义你的转换器:

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

然后像这样使用

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

(另一种解决方法是将图像命名为不同的名称,然后在更新源路径时它可以正常工作。)

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();
    }
}

【讨论】:

    【解决方案3】:

    所以现在我做了一个单独的procjet,只用于图片装订

    图像转换器代码:

    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;
        }
    }
    

    主窗口:

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

    在我的程序中我遇到了一些问题,所以我制作了这个独立项目以确保它可以正常工作。

    感谢大家的帮助!

    【讨论】:

    • 请注意,在我的情况下,有时在应用程序运行时覆盖图像时它不起作用,所以如果你发现一些问题尝试更多地使用转换器(好在所有这些逻辑现在在一个地方,所以它适用于你使用它的任何地方。
    • 现在我在我的应用程序中发现了问题。因为我在这个实例上有“PropertyChanged”,然后我更改了 Icon 并返回到“PropertyChanged”类......并且这样做到无穷大:)
    猜你喜欢
    • 2020-08-09
    • 2014-09-24
    • 2011-08-25
    • 1970-01-01
    • 2011-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多