Suren97 Ответов: 1

C# как загрузить изображения в список рядом друг с другом, WPF (openfiledialog)


текущее окно` WPF[^]

Мне нужно вот так` WPF[^]

Когда я нажимаю на кнопку Загрузить файл,я могу загружать изображения с моего компьютера с помощью OpenFileDialog,я не могу устанавливать изображения в последовательности, мне нужно после каждой загрузки изображения,изображение,установленное рядом с первым изображением, третье изображение, установленное рядом со вторым изображением и так далее.Как я могу это рассортировать?

Что я уже пробовал:

Это мой код`
<Window.Resources>
            <DataTemplate x:Key="ImageBox">
            <StackPanel>
                <Image Source="{Binding Path=Image}" Width="100" Height="50"/>
                <WrapPanel>
                    <Label Content="{Binding Path=Title}"/>
                </WrapPanel>
            </StackPanel>
        </DataTemplate>
    </Window.Resources>



<ListBox ScrollViewer.HorizontalScrollBarVisibility="Disabled" x:Name="lb" ItemTemplate="{StaticResource ImageBox}">
                                    <ListBox.ItemsPanel>
                                        <ItemsPanelTemplate>
                                            <WrapPanel/>
                                        </ItemsPanelTemplate>
                                    </ListBox.ItemsPanel>
                                </ListBox>


Это кнопка загрузки файла нажмите`
private void button1_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog op = new OpenFileDialog();
            op.Title = "Select a picture";
            op.Filter = "All supported graphics|*.jpg;*.jpeg;*.png|" +
              "JPEG (*.jpg;*.jpeg)|*.jpg;*.jpeg|" +
              "Portable Network Graphic (*.png)|*.png";
           
            if (op.ShowDialog() == true)
            {
                foreach (string filename in op.FileNames)
                    lb.Items.Add(System.IO.Path.GetFileName(filename));
            }
            paste();
        }





 private void paste()
        {
            ObservableCollection<Picture> pictures= new ObservableCollection<Picture>();
            lb.ItemsSource = pictures;
        }


 
 public class Picture
    {
        public string Title { get; set; }
        public string Image { get; set; }
        public Picture(string Title,string Image)
        {
            this.Title = Title;
            this.Image = Image;
        }
    }

1 Ответов

Рейтинг:
5

Graeme_Grant

ObservableCollection<Picture> pictures= new ObservableCollection<Picture>();lb.ItemsSource = pictures;

Три трюка с привязкой и тем ObservableCollection класс должен инициализировать его только один раз. Повторная инициализация его, как вы находитесь выше, нарушит привязку к коллекции.

Во-вторых, вам нужно только один раз установить свойство ListBox ItemsSource. Обычно оно задается в XAML, и, для кода, привязка кода к странице XAML :
public MainWindow()
{
    InitializeComponent();
    DataContext = this;
}

Поэтому, чтобы исправить свой код, вам нужно сделать следующее:
private void paste(IEnumerable<MyPicture> newPictures)
{
    MyPictures.Clear();
    foreach (var item in newPictures)
    {
        MyPictures.Add(item);
    }
}

И Pictures коллекция должна быть выставлена как свойство для того, чтобы Listbox правильно ее видел:
public ObservableCollection<MyPicture> 
MyPictures{ get; }
    = new ObservableCollection<MyPicture>();

Затем правильно использовать:
private void button1_Click(object sender, RoutedEventArgs e)
{
    OpenFileDialog op = new OpenFileDialog()
    {
        Title = "Select picture(s)",
        Filter = "All supported graphics|" +
                    "*.jpg;*.jpeg;*.png|" +
                    "JPEG (*.jpg;*.jpeg)|" +
                    "*.jpg;*.jpeg|" +
                    "Portable Network Graphic (*.png)" +
                    "|*.png",
        InitialDirectory = Environment.GetFolderPath(
            Environment.SpecialFolder.MyPictures),
        Multiselect = true
    };

    if (op.ShowDialog() == true)
    {
        paste(op.FileNames.Select(f => new MyPicture
        {
            Url = new Uri(f, UriKind.Absolute),
            Title = System.IO.Path.GetFileName(f)
        }));
    }
}

Примечание: MyPicture класс - это ваш собственный объект данных. Что-то вроде:
public class MyPicture
{
    public Uri Url { get; set; } // filename of image
    public string Title {get; set; }
}

Далее вам нужно исправить свой XAML. Вот вам пример:
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <Button Content="Load Images"

            Margin="10" Padding="10 5"

            HorizontalAlignment="Center"

            Click="Button_Click"/>
    <ListBox ItemsSource="{Binding MyPictures}"

                ScrollViewer.HorizontalScrollBarVisibility="Disabled"

                Grid.Row="1" Margin="10">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel Orientation="Horizontal" />
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid MaxWidth="200" Margin="10">
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <Image Source="{Binding Url}" />
                    <TextBlock Text="{Binding Title}"

                                HorizontalAlignment="Center"

                                Grid.Row="1" Margin="0 5"/>
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

Если вы хотите редактировать свойства с помощью системы привязки, то вам нужно будет реализовать INotifyPropertyChanged интерфейс для MyPicture класс. Вы можете прочитать больше здесь: Привязка данных (WPF) | Microsoft Docs[^]
[обновление] Вот полное кодовое решение:
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
    }

    public ObservableCollection<MyPicture> MyPictures { get; }
        = new ObservableCollection<MyPicture>();

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        OpenFileDialog op = new OpenFileDialog()
        {
            Title = "Select picture(s)",
            Filter = "All supported graphics|" +
                        "*.jpg;*.jpeg;*.png|" +
                        "JPEG (*.jpg;*.jpeg)|" +
                        "*.jpg;*.jpeg|" +
                        "Portable Network Graphic (*.png)" +
                        "|*.png",
            InitialDirectory = Environment.GetFolderPath(
                Environment.SpecialFolder.MyPictures),
            Multiselect = true
        };

        if (op.ShowDialog() == true)
        {
            paste(op.FileNames.Select(f => new MyPicture
            {
                Url = new Uri(f, UriKind.Absolute),
                Title = System.IO.Path.GetFileName(f)
            }));
        }
    }

    private void paste(IEnumerable<MyPicture> newPictures)
    {
        MyPictures.Clear();
        foreach (var item in newPictures)
        {
            MyPictures.Add(item);
        }
    }
}

public class MyPicture
{
    public Uri Url { get; set; } // filename of image
    public string Title { get; set; }
}


Suren97

Большое вам спасибо, но есть одна проблема,картинки не сортируются рядом друг с другом, после каждой загрузки картинки,картинки устанавливаются друг на друга,как решить эту проблему?

Suren97

Ну, я нашел проблему, это причина моих фотографий.Clear(); в функции paste() большое вам спасибо.Я принимаю ваше решение :)

Graeme_Grant

Мы всегда рады вам.

Suren97

и,пожалуйста, не могли бы вы мне помочь, как я могу отредактировать название этой картины?У меня есть текстовое поле и кнопка в левой части,мне нужно написать новое имя для выбранного элемента в списке, и после нажатия на кнопку Сохранить название моего выбранного элемента должно измениться.Что я должен написать в кнопке Save click?Я написал фунтов.SelectedItem = textbox1.Text; но это не работает.Это скриншот ` http://prntscr.com/j04sfj

Graeme_Grant

Это уже другой вопрос. Не могли бы вы написать новый вопрос, и я отвечу на него там.

Suren97

да, конечно,подождите, пожалуйста

Suren97

Я уже выложил, можете посмотреть :)