WPF-在后面的代码中将图像绑定到相对URI

时间:2018-07-22 06:52:14

标签: c# wpf image binding relative

我为DataGrid对象创建了一个ImageColumn。但是我不知道如何将一个相对的图像路径绑定到它。 我需要类似的东西,但是在C#中。

<Image Source="pack://application:,,,/Images/Folder-icon.png"/>

这就是我创建ImageColumn的方式

public static DataGridTemplateColumn createImageColumn(string header, Binding b, Size s)
{
    DataTemplate dt = new DataTemplate();
    dt.DataType = typeof(Image);
    FrameworkElementFactory dtFactory = new FrameworkElementFactory(typeof(StackPanel));
    dtFactory.Name = "stack";
    dtFactory.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);


    FrameworkElementFactory imageHolder = new FrameworkElementFactory(typeof(Image));
    imageHolder.Name = header;
    imageHolder.SetValue(Image.SourceProperty, b);
    imageHolder.SetValue(Image.WidthProperty, s.Width);
    imageHolder.SetValue(Image.HeightProperty, s.Height);
    imageHolder.SetValue(Image.HorizontalAlignmentProperty, HorizontalAlignment.Center);
    imageHolder.SetValue(Image.VerticalAlignmentProperty, VerticalAlignment.Center);
    dtFactory.AppendChild(imageHolder);

    dt.VisualTree = dtFactory;

    DataGridTemplateColumn imageColumn = new DataGridTemplateColumn();
    imageColumn.Header = header;
    imageColumn.CellTemplate = dt;
    return imageColumn;
}

这是我当前的绑定方式。

Binding b = new Binding();
b.Path = new PropertyPath("IMAGE_PATH");
b.RelativeSource = new RelativeSource(RelativeSourceMode.Self);

编辑: “ IMAGE_PATH”是DataGrid的另一列。它保存了图像文件的相对路径(相对于应用程序根目录)。 如果我添加一条绝对路径,它将起作用。但是没有相对路径。

有关该项目的更多信息: 数据网格保存项目信息(零件号,图像,描述,价格)。用户应该能够添加图像。图像将被复制到应用程序中,例如:

APPLICATION_ROOT / Images / Item / file.png

此路径将保存在数据库的“ IMAGE_PATH”列中。

Images / Item / file.png

此路径以后将用于在ImageColumn中绘制图像。但是,这是相对路径,并且仅适用于绝对路径。

希望这更加清楚。谢谢!

2 个答案:

答案 0 :(得分:0)

有一些要解决的问题:

  1. 图像的SourceProperty需要一个ImageSource对象,我想在您的情况下,DataContext-Property'IMAGE_PATH'的类型为字符串
  2. Binding RelativePath.Self表示要查找控件的“ own”属性,请设置绑定,除非您有一个带有DP'IMAGE_PATH'的自定义图像控件作为内部将其转换为BitmapImage的字符串,否则工作。
  3. 您没有提供您的ViewModel和Datagrid的ItemsSource绑定。您将需要一个具有ObservableCollection 属性的ViewModel并将其绑定到DataGrid ItemsSource属性
  4. “ YourType”类将需要一个属性,其中包含要在DataGridTemplateColumn的绑定中使用的BitmapImage。
  5. 我倾向于将图像构建为资源(Sol.Explorer->图像-> Build Action ...),这样'Pack'-Uri变得更简单,您不必在输出文件夹中复制图像。 / li>

这是一个可行的版本(可能并不完美,但可以正常工作)

Window xaml:

<Window x:Class="WpfApp1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApp1"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
<Grid>
    <DataGrid AutoGenerateColumns="False"  
              Name="dg1" ItemsSource="{Binding Items}"
              CanUserAddRows="False" />
</Grid>

窗口的代码隐藏(这不是太优雅,仅用于测试)

namespace WpfApp1
{
public partial class MainWindow : Window
 {
  public MainWindow()
    {
        InitializeComponent();
        var x = new VM();
        x.Items.Add(new Class2 { IMAGE_PATH = "dir_16p.png", value = "123" });
        x.Items.Add(new Class2 { IMAGE_PATH = "dir_blue_16p.png", value = "456" });
        DataContext = x;
        dg1.Columns.Add(Class1.createImageColumn("test", new Size(16, 16)));
        dg1.Columns.Add(new DataGridTextColumn { Binding = new Binding("value"), 
        Header = "Value" });
    }
  }
}

Class1.cs

using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace WpfApp1
{
class Class1
{
    public static DataGridTemplateColumn createImageColumn(string header, Size s)
    {
        Binding b = new Binding("img");

        DataTemplate dt = new DataTemplate();
        dt.DataType = typeof(Class2);
        var dtFactory = new FrameworkElementFactory(typeof(StackPanel));
        dtFactory.Name = "stack";
        dtFactory.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);


        FrameworkElementFactory imageHolder = new 
        FrameworkElementFactory(typeof(Image));
        imageHolder.SetValue(Image.SourceProperty, b);
        imageHolder.SetValue(Image.WidthProperty, s.Width);
        imageHolder.SetValue(Image.HeightProperty, s.Height);
        imageHolder.SetValue(Image.HorizontalAlignmentProperty, 
        HorizontalAlignment.Center);
        imageHolder.SetValue(Image.VerticalAlignmentProperty, 
        VerticalAlignment.Center);

        dtFactory.AppendChild(imageHolder);

        var  imageColumn = new DataGridTemplateColumn();
        imageColumn.Header = header;
        imageColumn.CellTemplate = dt;
        return imageColumn;
    }

}
}

Class2

using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Media.Imaging;

namespace WpfApp1
{
class Class2 : INotifyPropertyChanged
{

    private string _IMAGE_PATH;
    public string IMAGE_PATH
    {
        get { return _IMAGE_PATH; }
        set
        {
            _IMAGE_PATH = value;
            NotifyPropertyChanged();
            img = new BitmapImage(
                new Uri("pack://application:,,,/Images/" + value));
        }
    }

    private BitmapImage _img;
    public BitmapImage img
    {
        get
        {

            return _img;
        }
        set
        {
            _img = value;
            NotifyPropertyChanged();
        }
    }


    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }


    private string _value;
    public string value
    {
        get { return _value; }
        set { _value = value; NotifyPropertyChanged(); }
    }
}
}

还有ViewModel VM.cs

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace WpfApp1
{
class VM : INotifyPropertyChanged
{

    public VM()
    {
        Items = new ObservableCollection<Class2>();
    }

    private ObservableCollection<Class2> _Items;
    public ObservableCollection<Class2> Items
    {
        get { return _Items; }
        set { _Items = value; NotifyPropertyChanged(); }
    }


    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
}

Build Action for res-images

答案 1 :(得分:-2)

尝试一下

Auto Series Key Data Column