动态添加图像到ListView

时间:2017-10-18 10:24:19

标签: c# wpf mvvm

在我的程序中,我有一个listview,我可以在其中添加我的文件夹中的图像。

所选图像应在程序中大显示。

现在我只能显示刚刚从我的文件夹中打开的图像。

我的问题是,如何将图像添加到listview并显示所选图像?

我知道我需要为所选图像添加变量,并为listview中的图像提供可观察的集合。

我的Xaml

<Grid x:Name="GridLoadedImage" HorizontalAlignment="Left" VerticalAlignment="Top">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="MouseLeftButtonDown">
            <i:InvokeCommandAction Command ="{Binding MouseLeftButtonDownCommnad}" />
        </i:EventTrigger>
        <i:EventTrigger EventName="MouseLeftButtonUp">
            <i:InvokeCommandAction Command="{Binding MouseLeftButtonUpCommand}" />
        </i:EventTrigger>
        <i:EventTrigger EventName="MouseMove">
            <i:InvokeCommandAction Command="{Binding MouseMoveCommand}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
    <Grid.LayoutTransform>
        <ScaleTransform ScaleX="{Binding ElementName=slider1, Path=Value}" ScaleY="{Binding ElementName=slider1, Path=Value}"/>
    </Grid.LayoutTransform>
    <Image x:Name="_image" Margin="10" Source="{Binding CurrentImage.ImagePath, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
<Grid>
    <ListView Margin="10" ItemsSource="{Binding Image, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
        <ListViewItem>
            <StackPanel Orientation="Horizontal">
                <Image Source="{Binding Image}" MaxHeight="40"/>
            </StackPanel>
        </ListViewItem>
    </ListView>
</Grid>

我的ViewModel

public MainViewModel()
{
    SaveCommand = new ViewModelBase(this.saveFile);
    CropCommand = new ViewModelBase(this.Croping);
    ResizeCommand = new ViewModelBase(this.Resize);
    Image = new ObservableCollection<ImageModel>();
}

打开

 ICommand _openCommand;
    public ICommand OpenCommand
    {
        get
        {
            if (_openCommand == null)
            {
                _openCommand = new ViewModelBase(param => Open());
            }
            return _openCommand;
        }
    }
    private void Open()
    {

        Microsoft.Win32.OpenFileDialog open = new Microsoft.Win32.OpenFileDialog();
        open.DefaultExt = (".png");
        open.Filter = "JPG (*.jpg)|*.jpg|PNG (*.png)|*.png|All files (*.*)|*.*";
        BitmapImage myBitmapImage = new BitmapImage();

        if (open.ShowDialog() == true)
        myBitmapImage.BeginInit();
        myBitmapImage.UriSource = new Uri(open.FileName);
        myBitmapImage.EndInit();
        this.currentImage.ImagePath = myBitmapImage;           
    }

ImageModel

 BitmapSource imagePath;
    public BitmapSource ImagePath
    {
        get { return imagePath; }
        set
        {
            imagePath = value;
            OnPropertyChanged("ImagePath");
        }
    }

也许我的做法错了?欢迎提出建议,因为我不熟悉MVVM和WPF

1 个答案:

答案 0 :(得分:-1)

你的ImageModel应该有一个Image属性,类型为string,Uri或ImageSource,例如。

public class ImageModel
{
    public ImageSource Image { get; set; }
}

MainViewModel中的collection属性应最好命名为Images而不是Image,并且应该有CurrentImage属性:

public class MainViewModel : INotifyPropertyChanged
{
    public ObservableCollection<ImageModel> Images { get; }
        = new ObservableCollection<ImageModel>();

    private ImageModel currentImage;
    public ImageModel CurrentImage
    {
        get { return currentImage; }
        set
        {
            currentImage = value;
            PropertyChanged?.Invoke(this,
                new PropertyChangedEventArgs(nameof(CurrentImage)));
        }
    }

    ...
}

现在绑定一个ListView或ListBox的ItemsSourceSelectedItem,并像这样声明它的ItemTemplate(StackPanel可能是多余的):

<ListBox ItemsSource="{Binding Images}" SelectedItem="{Binding CurrentImage}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <Image Source="{Binding Image}" MaxHeight="40" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

现在可以在另一个Image元素中显示所选图像,如下所示:

<Image Source="{Binding CurrentImage.Image}"/>

打开图像文件时,还应将其添加到Images集合中,如下所示:

if ((bool)open.ShowDialog())
{
    var item = new ImageModel
    {
        Image = new BitmapImage(new Uri(open.FileName))
    };

    Images.Add(item);
    CurrentImage = item;
}