C# WPF自定义控件,图像错误显示

C# WPF自定义控件,图像错误显示,c#,wpf,image,datagrid,C#,Wpf,Image,Datagrid,我创建了派生图像控件类,它接受图像路径, 但是当我使用绑定时,一些图像显示其他图像;尽管数据是正确的。是图像失效还是什么 当我尝试使用默认图像控件时,显示图像没有问题 ImageUserControl.cs using System; using System.IO; using System.Windows; using System.Windows.Controls; using System.Windows.Media.Imaging; namespace WpfApp1 {

我创建了派生图像控件类,它接受图像路径, 但是当我使用绑定时,一些图像显示其他图像;尽管数据是正确的。是图像失效还是什么

当我尝试使用默认图像控件时,显示图像没有问题

ImageUserControl.cs

using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;

namespace WpfApp1
{
    static class BitmapHelpers
    {
        public static BitmapImage ToBitmapImage(Uri source)
        {
            var bitmap = new BitmapImage();
            bitmap.BeginInit();
            bitmap.UriSource = source;
            bitmap.CacheOption = BitmapCacheOption.OnLoad;
            bitmap.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
            bitmap.EndInit();
            return bitmap;
        }

        public static string GetThumbnailPath(string fullPath)
        {
            return Path.Combine(Path.GetDirectoryName(fullPath),
                "thumb" + Path.GetFileName(fullPath));
        }
    }

    public class ImageUserControl : Image
    {
        public static readonly DependencyProperty CanOpenFileExternallyProperty;
        public static readonly DependencyProperty UseThumbnailProperty;
        public static readonly DependencyProperty UriSourceProperty;

        private string OriginalPath { get; set; }
        private string ThumbnailPath { get; set; }

        static ImageUserControl()
        {
            UseThumbnailProperty = DependencyProperty.Register("UseThumbnail", typeof(bool), 
                typeof(ImageUserControl), 
                new FrameworkPropertyMetadata(false));
            UriSourceProperty = DependencyProperty.Register("UriSource", typeof(string), 
                typeof(ImageUserControl), 
                new FrameworkPropertyMetadata(null, OnUriSourcePropertyChanged));
        }

        private static void OnUriSourcePropertyChanged(DependencyObject d,
                    DependencyPropertyChangedEventArgs e)
        {
            ImageUserControl uc = d as ImageUserControl;
            uc.UriSource = e.NewValue.ToString();
        }

        public const string UriSourcePropertyName = "UriSource";

        public string UriSource
        {
            get
            {
                return (string)GetValue(UriSourceProperty);
            }
            set
            {
                try
                {
                    SetValue(UriSourceProperty, value);
                    OriginalPath = value;
                    if (UseThumbnail && !string.IsNullOrWhiteSpace(value))
                    {
                        ThumbnailPath = BitmapHelpers.GetThumbnailPath(value);
                        if (System.IO.File.Exists(ThumbnailPath))
                        {
                            this.Source = BitmapHelpers.ToBitmapImage(new Uri(ThumbnailPath));
                            return;
                        }
                    }
                    if (!string.IsNullOrWhiteSpace(value) && System.IO.File.Exists(value))
                        this.Source = BitmapHelpers.ToBitmapImage(new Uri(value));
                    else
                        this.Source = null;
                }
                catch { this.Source = null; }
            }
        }

        public event EventHandler ImageChanged;

        public void OnImageChanged()
        {
            ImageChanged?.Invoke(this, null);
        }

        public ImageUserControl()
        {
        }

        public bool UseThumbnail
        {
            get { return (bool)GetValue(UseThumbnailProperty); }
            set { SetValue(UseThumbnailProperty, value); }
        }
    }
}
StudentViewModel.cs

using WpfApp1.Model;
using System.Collections.ObjectModel;

namespace WpfApp1.ViewModel
{
    public class StudentViewModel
    {
        public ObservableCollection<Student> Students { get; set; }

        public void LoadStudents()
        {
            ObservableCollection<Student> students = new ObservableCollection<Student>();

            students.Add(new Student { FirstName = "One", LastName = "Red", Image= @"C:\Users\Public\Pictures\Sample Pictures\Desert.jpg" });
            students.Add(new Student { FirstName = "Two", LastName = "Green", Image= @"C:\Users\Public\Pictures\Sample Pictures\Hydrangeas.jpg" });
            students.Add(new Student { FirstName = "Three", LastName = "Blue", Image= @"C:\Users\Public\Pictures\Sample Pictures\Jellyfish.jpg" });
            students.Add(new Student { FirstName = "Four", LastName = "Cyan", Image= @"C:\Users\Public\Pictures\Sample Pictures\Koala.jpg" });
            students.Add(new Student { FirstName = "Five", LastName = "Magenta" });
            students.Add(new Student { FirstName = "Six", LastName = "Yellow", Image = @"C:\Users\Public\Pictures\Sample Pictures\Desert.jpg" });
            students.Add(new Student { FirstName = "Seven", LastName = "Black", Image = @"C:\Users\Public\Pictures\Sample Pictures\Hydrangeas.jpg" });
            students.Add(new Student { FirstName = "Eight", LastName = "White", Image = @"C:\Users\Public\Pictures\Sample Pictures\Jellyfish.jpg" });
            students.Add(new Student { FirstName = "Nine", LastName = "Orange", Image = @"C:\Users\Public\Pictures\Sample Pictures\Koala.jpg" });
            students.Add(new Student { FirstName = "Ten", LastName = "Gray" });

            Students = students;
        }
    }
}
使用WpfApp1.Model;
使用System.Collections.ObjectModel;
命名空间WpfApp1.ViewModel
{
公共课堂学生视图模型
{
公共可观察集合学生{get;set;}
公立学校学生()
{
ObservableCollection学生=新ObservableCollection();
添加(新学生{FirstName=“One”,LastName=“Red”,Image=@“C:\Users\Public\Pictures\Sample Pictures\dest.jpg”});
添加(新学生{FirstName=“Two”,LastName=“Green”,Image=@“C:\Users\Public\Pictures\Sample Pictures\Hydrangeas.jpg”});
添加(新学生{FirstName=“Three”,LastName=“Blue”,Image=@“C:\Users\Public\Pictures\Sample Pictures\Jellyfish.jpg”});
添加(新学生{FirstName=“Four”,LastName=“Cyan”,Image=@“C:\Users\Public\Pictures\Sample Pictures\Koala.jpg”});
添加(新学生{FirstName=“Five”,LastName=“Magenta”});
添加(新学生{FirstName=“Six”,LastName=“Yellow”,Image=@“C:\Users\Public\Pictures\Sample Pictures\dest.jpg”});
添加(新学生{FirstName=“Seven”,LastName=“Black”,Image=@“C:\Users\Public\Pictures\Sample Pictures\Hydrangeas.jpg”});
添加(新学生{FirstName=“八”,LastName=“白”,Image=@“C:\Users\Public\Pictures\Sample Pictures\jellyphish.jpg“});
添加(新学生{FirstName=“Nine”,LastName=“Orange”,Image=@“C:\Users\Public\Pictures\Sample Pictures\Koala.jpg”});
添加(新学生{FirstName=“Ten”,LastName=“Gray”});
学生=学生;
}
}
}
MainWindow.xaml

<Window x:Class = "WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable = "d"
        Loaded="StudentViewControl_Loaded"
Title = "MainWindow" Height = "350" Width = "525">

    <DataGrid Name="DataGridStudents" ItemsSource="{Binding Students}" AutoGenerateColumns="False" CanUserAddRows="False">
        <DataGrid.Columns>
            <DataGridTemplateColumn>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <local:ImageUserControl Height="50" UriSource="{Binding Image, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" UseThumbnail="True" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTextColumn Header="FirstName" Binding="{Binding Image}" />
            <DataGridTextColumn Header="FirstName" Binding="{Binding FirstName}" />
            <DataGridTextColumn Header="LastName" Binding="{Binding LastName}" />
        </DataGrid.Columns>
    </DataGrid>

</Window>


请注意,在依赖项属性的CLR包装中,不能调用除GetValue和SetValue之外的任何东西。将所有代码从UriSource setter移动到OnUriSourcePropertyChanged方法。另请注意,在UriSource绑定上设置Mode=TwoWay和UpdateSourceTrigger=PropertyChanged是没有意义的。“这没有任何效果。”克莱门斯以前感谢过你。URI源设置器已移动,但图像再次显示其他图像:-(我设置的绑定是单向的,因为我认为图像是从外部修改的。