代码之家  ›  专栏  ›  技术社区  ›  urini

图像urisource和数据绑定

  •  59
  • urini  · 技术社区  · 16 年前

    我正在尝试将自定义对象列表绑定到WPF图像,如下所示:

    <Image>
        <Image.Source>
            <BitmapImage UriSource="{Binding Path=ImagePath}" />
        </Image.Source>
    </Image>
    

    但它不起作用。这是我得到的错误:

    “必须设置属性”“urisource”“或属性”“streamsource”“。”

    我错过了什么?

    6 回复  |  直到 7 年前
        1
  •  75
  •   Clemens    7 年前

    WPF具有特定类型的内置转换器。如果您绑定图像的 Source 属性到 string Uri 值,在引擎盖下,WPF将使用 ImageSourceConverter 将值转换为 ImageSource .

    所以

    <Image Source="{Binding ImageSource}"/>
    

    如果ImageSource属性是图像的有效URI的字符串表示形式,则可以工作。

    当然,您可以滚动自己的绑定转换器:

    public class ImageConverter : IValueConverter
    {
        public object Convert(
            object value, Type targetType, object parameter, CultureInfo culture)
        {
            return new BitmapImage(new Uri(value.ToString()));
        }
    
        public object ConvertBack(
            object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }
    

    像这样使用:

    <Image Source="{Binding ImageSource, Converter={StaticResource ImageConverter}}"/>
    
        2
  •  22
  •   Drew Noakes    15 年前

    This article 由AtulGupta提供的示例代码涵盖了几个场景:

    1. 常规资源映像绑定到XAML中的源属性
    2. 绑定资源映像,但来自代码隐藏
    3. 使用application.getresourcestream绑定代码隐藏中的资源映像
    4. 通过内存流从文件路径加载图像(同样适用于从数据库加载日志图像数据)
    5. 从文件路径加载图像,但使用绑定到文件路径属性
    6. 将图像数据绑定到用户控件,该用户控件通过依赖属性在内部具有图像控件
    7. 与第5点相同,但也要确保文件不会被锁定在硬盘上。
        3
  •  18
  •   palehorse    16 年前

    您也可以简单地设置源属性,而不是使用子元素。为此,类需要将图像作为位图图像返回。下面是一个例子,说明我是如何做到这一点的

    <Image Width="90" Height="90" 
           Source="{Binding Path=ImageSource}"
           Margin="0,0,0,5" />
    

    类属性就是

    public object ImageSource {
        get {
            BitmapImage image = new BitmapImage();
    
            try {
                image.BeginInit();
                image.CacheOption = BitmapCacheOption.OnLoad;
                image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
                image.UriSource = new Uri( FullPath, UriKind.Absolute );
                image.EndInit();
            }
            catch{
                return DependencyProperty.UnsetValue;
            }
    
            return image;
        }
    }
    

    我想这可能比值转换器要多一些工作,但这是另一种选择。

        4
  •  8
  •   Dale Ragan    16 年前

    您需要实现 IValueConverter 将URI转换为图像的接口。ivalueConverter的转换实现如下所示:

    BitmapImage image = new BitmapImage();
    image.BeginInit();
    image.UriSource = new Uri(value as string);
    image.EndInit();
    
    return image;
    

    然后您需要在绑定中使用转换器:

    <Image>
        <Image.Source>
            <BitmapImage UriSource="{Binding Path=ImagePath, Converter=...}" />
        </Image.Source>
    </Image>
    
        5
  •  6
  •   Community Reversed Engineer    7 年前

    这里选择的答案的问题是,当来回导航时,每次显示页面时都会触发转换器。

    这将导致连续创建新的文件句柄,并阻止删除该文件的任何尝试,因为该文件仍在使用中。这可以通过使用Process Explorer进行验证。

    如果图像文件可能在某个时间点被删除,则可以使用如下转换器: using XAML to bind to a System.Drawing.Image into a System.Windows.Image control

    此内存流方法的缺点是,每次加载和解码图像时都无法进行缓存: 要防止图像被多次解码,请从URI分配image.source属性,而不是使用内存流 来源:“使用XAML的Windows应用商店应用程序的性能提示”

    为了解决性能问题,可以使用存储库模式提供缓存层。缓存可能发生在内存中,这可能导致内存问题,或者作为临时文件夹中的缩略图文件,当应用程序退出时可以清除该文件夹。

        6
  •  4
  •   Karthik Krishna Baiju    11 年前

    您可以使用

    ImageSourceConverter类

    得到你想要的

        img1.Source = (ImageSource)new ImageSourceConverter().ConvertFromString("/Assets/check.png");