# Вывод данных согласно макета (ListBox, Image)
`MainWindow.xaml.cs`
```
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using wpf_listbox.models;
using System.Threading.Tasks;
using System;
using System.Formats.Asn1;
using System.Globalization;
using System.IO;
using System.Runtime.Serialization.Json;


namespace wpf_listbox
{
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void Invalidate()
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs("PeopleList"));
        }
        public string selectedGender = "Пол";
        public PeopleAge? selectedAge = null;
        public string selectedPlace = "Место";

        private IEnumerable<People> _PeopleList;
        public IEnumerable<People> PeopleList
        {
            get
            {
                var res = _PeopleList;

                // фильтруем по возрасту
                res = res
                     .Where(c => (c.Gender == selectedGender || selectedGender == "Пол"))
                     .Where(c => (selectedAge == null || (c.Age >= selectedAge.AgeFrom && c.Age < selectedAge.AgeTo)))
                     .Where(c => (c.Place == selectedPlace || selectedPlace == "Место"));
                // если фильтр не пустой, то ищем ВХОЖДЕНИЕ подстроки поиска в кличке без учета регистра
                if (searchFilter != "")
                    res = res.Where(c => c.Name.IndexOf(
                        searchFilter,
                        StringComparison.OrdinalIgnoreCase) >= 0 || c.Gender.IndexOf(
                        searchFilter,
                        StringComparison.OrdinalIgnoreCase) >= 0 || c.Place.IndexOf(
                        searchFilter,
                        StringComparison.OrdinalIgnoreCase) >= 0);
                if (sortAsc) res = res.OrderBy(c => c.Price);
                else res = res.OrderByDescending(c => c.Price);
                if (sortAsc) res = res.OrderBy(c => c.Price);
                else res = res.OrderByDescending(c => c.Price);

                return res;
            }
            set
            {
                _PeopleList = value;
            }
        }


        public List<PeopleGender> PeopleGenderList { get; set; }
        public List<PeopleAge> PeopleAgeList { get; set; }
        public List<PeoplePlace> PeoplePlaceList { get; set; }
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
            Globals.dataProvider = new JSONDataProvider();
            PeopleList = Globals.dataProvider.getPeople();
            PeopleGenderList = Globals.dataProvider.getGender().ToList();
            PeopleGenderList.Insert(0, new PeopleGender { title = "Пол" });
            PeopleAgeList = Globals.dataProvider.getAge().ToList();
            PeoplePlaceList = Globals.dataProvider.getPlace().ToList();
            PeoplePlaceList.Insert(0, new PeoplePlace { title = "Место" });
        }



        private void ExitButton_Click(object sender, RoutedEventArgs e)
        {
            Application.Current.Shutdown();

        }
        private string searchFilter = "";

        private void SearchFilter_KeyUp(object sender, KeyEventArgs e)
        {
            searchFilter = SearchFilterTextBox.Text;
            Invalidate();
        }

        private void GenderFilterComboBox_SelectionChanged_1(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            selectedGender = (GenderFilterComboBox.SelectedItem as PeopleGender).title;
            Invalidate();
        }
        private void AgeFilterComboBox_SelectionChanged_2(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            selectedAge = AgeFilterComboBox.SelectedItem as PeopleAge;
            Invalidate();
        }
        private void PlaceFilterComboBox_SelectionChanged_3(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            selectedPlace = (PlaceFilterComboBox.SelectedItem as PeoplePlace).title;
            Invalidate();
        }
        private bool sortAsc = true;

        private void RadioButton_Checked(object sender, RoutedEventArgs e)
        {
            sortAsc = (sender as RadioButton).Tag.ToString() == "1";
            Invalidate();
        }



    }

    public class LocalDataProvider : IDataProvider
    {
        public IEnumerable<PeopleGender> getGender()
        {
            return new PeopleGender[]
            {
                new PeopleGender()
                {
                    title="Ж"

                },
                new PeopleGender()
                {
                    title="М"
                }
            };
        }
        public IEnumerable<PeopleAge> getAge()
        {
            return new PeopleAge[]
            {
                new PeopleAge()
                {
                    title="Все возраста",
                    AgeFrom=0,
                    AgeTo=99

                },



                new PeopleAge()
                {
                    title="Подростки",
                    AgeFrom=15,
                    AgeTo=18

                },
                new PeopleAge()
                {
                    title="Молодые",
                    AgeFrom=18,
                    AgeTo=30

                },
                new PeopleAge()
                {
                    title="В Возврасте",
                    AgeFrom=30,
                    AgeTo=99

                }

            };

        }
        public IEnumerable<PeoplePlace> getPlace()
        {
            return new PeoplePlace[]
            {
                new PeoplePlace()
                {
                    title="Набережная"

                },
                new PeoplePlace()
                {
                    title="Йолка"
                },
                new PeoplePlace()
                {
                    title="Бульвар"
                },
                new PeoplePlace()
                {
                    title="ЙОТК"
                },
               new PeoplePlace()
                {
                    title="Планета"
                },
               new PeoplePlace()
                {
                    title="Ремзавод"
                },
               new PeoplePlace()
                {
                    title="Медведево"
                },
               new PeoplePlace()
                {
                    title="Пляж"
                },

            };
        }
        public IEnumerable<People> getPeople()
        {
            return new People[]{
            new People
            {
                Age=19,
                Name="Марина",
                Gender="Ж",
                Price=500,
                Place="Набережная"
            },
            new People
            {
                Price=9600,
                Name="Вика",
                Age=21,
                Gender="Ж",
                Place="Йолка"
            },
            new People
            {
                Price=50,
                Name="Кристина",
                Age=17,
                Gender="Ж",
                Place="Планета"
            },
            new People
            {
                Price=2000,
                Name="Анджелика",
                Age=16,
                Gender="Ж",
                Place="Бульвар"
            },
            new People
            {
                Price=1500,
                Name="Костя",
                Age=15,
                Gender="М",
                Place="Бульвар"
            },
            new People
            {
                Price=5000,
                Name="Вероника",
                Age=25,
                Gender="Ж",
                Place="Набережная"
            },
            new People
            {
                Price=1000,
                Name="Савелий",
                Age=20,
                Gender="М",
                Place="Пляж"
            },
            new People
            {
                Price=1500,
                Name="Александр",
                Age=39,
                Gender="М",
                Place="ЙОТК"
            },
            new People
            {
                Price=500,
                Name="Евгений",
                Age=18,
                Gender="М",
                Place="Медведево"
            },
            new People
            {
                Price=2500,
                Name="Давид",
                Age=18,
                Gender="М",
                Place="Ремзавод"
            },

        };

        }

        IEnumerable<models.People> IDataProvider.getPeople()
        {
            throw new NotImplementedException();
        }
    }
    public class JSONDataProvider : LocalDataProvider, IDataProvider
    {
        private List<People> _PeopleList;

        public JSONDataProvider()
        {
            var serializer = new DataContractJsonSerializer(typeof(People[]));
            using (var sr = new StreamReader("./data.json"))
            {
                _PeopleList = ((People[])serializer.ReadObject(sr.BaseStream)).ToList();
            }
        }

        public IEnumerable<People> getPeople()
        {
            return _PeopleList;
        }
    }

}
```
`MainWindow.xaml`
```
<Window x:Class="wpf_listbox.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:wpf_listbox"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="880">
    <Window.Resources>
        <BitmapImage 
        x:Key='defaultImage' 
        UriSource='./img/1.webp' />
    </Window.Resources>
    <Grid ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition />
            <RowDefinition Height="auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="200"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <!-- типа логотип компании -->
        <Image 
        Source="./img/1.webp"
        Grid.RowSpan="2" HorizontalAlignment="Right"/>
        <ListBox
            Grid.Column="1"
    Grid.Row="1"
    Background="White"
    ItemsSource="{Binding PeopleList}" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel 
            HorizontalAlignment="Center" />
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <ListBox.ItemTemplate>

    <DataTemplate>
        <Border 
            BorderThickness="1" 
            BorderBrush="Black" 
            CornerRadius="5">
            <Grid Width="200"
    Margin="10" 
    HorizontalAlignment="Stretch">

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="64"/>
        <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="auto"/>
            </Grid.ColumnDefinitions>
            <Image
    Width="64" 
    Height="64"
    Source="{Binding ImageBitmap,TargetNullValue={StaticResource defaultImage}}" />
            <StackPanel
    Grid.Column="1"
    Margin="5"
    Orientation="Vertical">

                <TextBlock 
        Text="{Binding Name}"/>
                <TextBlock
             Text="{Binding Price}"/>

                <TextBlock 
        Text="{Binding Place}"/>
            </StackPanel>
            <TextBlock 
    Grid.Column="2"
    Text="{Binding Age}"/>
    </Grid>
    </Border>
    </DataTemplate>
    </ListBox.ItemTemplate>

</ListBox>

    <StackPanel 
        Orientation="Vertical"
        Grid.RowSpan="3"
        VerticalAlignment="Bottom">
            <Button 
            x:Name="ExitButton"
            Content="Выход" 
            Click="ExitButton_Click"
            Height="50"/>
        </StackPanel>

        <WrapPanel
        Orientation="Horizontal"
        Grid.Column="1"
        MinHeight="50">
            <Label 
    Content="искать" 
    VerticalAlignment="Center"/>
            <TextBox
    Width="200"
    VerticalAlignment="Center"
    x:Name="SearchFilterTextBox" 
    KeyUp="SearchFilter_KeyUp"/>

            <ComboBox
    Name="GenderFilterComboBox"
    SelectionChanged="GenderFilterComboBox_SelectionChanged_1"
    VerticalAlignment="Center"
    MinWidth="100"
    SelectedIndex="0"
    ItemsSource="{Binding PeopleGenderList}">

                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <Label 
                Content="{Binding title}"/>
                    </DataTemplate>
                </ComboBox.ItemTemplate>
            </ComboBox>
            <Label 
    Content="Возраст:"
    VerticalAlignment="Center"/>
            <ComboBox
    Name="AgeFilterComboBox"
    SelectionChanged="AgeFilterComboBox_SelectionChanged_2"
    VerticalAlignment="Center"
    MinWidth="100"
    SelectedIndex="0"
    ItemsSource="{Binding PeopleAgeList}">

                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <Label 
            Content="{Binding title}"/>
                    </DataTemplate>
                </ComboBox.ItemTemplate>
            </ComboBox>
            <Label 
    Content="Место:"
    VerticalAlignment="Center"/>
            <ComboBox
    Name="PlaceFilterComboBox"
    SelectionChanged="PlaceFilterComboBox_SelectionChanged_3"
    VerticalAlignment="Center"
    MinWidth="100"
    SelectedIndex="0"
    ItemsSource="{Binding PeoplePlaceList}">

                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <Label 
            Content="{Binding title}"/>
                    </DataTemplate>
                </ComboBox.ItemTemplate>
            </ComboBox>
            <Label 
    Content="Цена:" 
    VerticalAlignment="Center"/>
            <RadioButton
    GroupName="Price"
    Tag="1"
    Content="Сначала недорогие"
    IsChecked="True"
    Checked="RadioButton_Checked"
    VerticalAlignment="Center"/>
            <RadioButton
    GroupName="Price"
    Tag="2"
    Content="Сначала дорогие"
    Checked="RadioButton_Checked"
    VerticalAlignment="Center"/>
            <!-- минимальную высоту я тут поставил, чтобы верхнюю строку сетки было видно. В реальном приложении она не нужна -->
        </WrapPanel>
    </Grid>
</Window>
```
`IDataProvider.cs`
```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static wpf_listbox.models.Globals;
using System.Threading.Tasks;
using System.Collections.Generic;
using wpf_listbox;
using wpf_listbox.models;

namespace wpf_listbox.models
{

    interface IDataProvider
    {
        IEnumerable<People> getPeople();
        IEnumerable<PeopleGender> getGender();
        IEnumerable<PeopleAge> getAge();
        IEnumerable<PeoplePlace> getPlace();
    }

    class Globals
    {
        public static IDataProvider dataProvider;


    }
}
```
`Class2.cs`
```
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading.Tasks;



namespace wpf_listbox.models
{
    public class PeopleGender
    {
        public string title { get; set; }
    }
    public class PeopleAge
    {
        public string title { get; set; }
        public int AgeFrom { get; set; }
        public int AgeTo { get; set; }
    }
    public class PeoplePlace
    {
        public string title { get; set; }

    }
}
```
`People.cs`
```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static wpf_listbox.models.Globals;
using System.Threading.Tasks;
using System.Collections.Generic;
using wpf_listbox;
using CsvHelper;
using System.Diagnostics;
using wpf_listbox.models;
using static wpf_listbox.MainWindow;
using System.IO;
using System.Globalization;
using System.Runtime.Serialization;

namespace wpf_listbox.models
{
    [DataContract]
    public class People
    {
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public int Age { get; set; }
        [DataMember]
        public int Price { get; set; }
        [DataMember]
        public string Gender { get; set; }
        [DataMember]
        public string Photo { get; set; }
        [DataMember]
        public string Place { get; set; }
        [DataMember]
        public bool IsFavorite { get; set; }
        [DataMember(Name = "dateOfConnections")]
        private string? stringDate { get; set; }

        [IgnoreDataMember]
        public DateTime? dateOfConnections
        {
            get
            {
                return stringDate == null ? null : DateTime.Parse(stringDate);
            }
            set
            {
                stringDate = value.ToString();
            }
        }

        public Uri? ImageBitmap
        {
            get
                {
                    var imageName = Environment.CurrentDirectory + "/img/" + (Photo ?? "");
                    return System.IO.File.Exists(imageName) ? new Uri(imageName) : null;
                }
            }
    }
}
```
`data.json`
```
[
	{
		"Name": "Марина",
		"Age":19,
		"Price":500,
		"Gender": "Ж",
		"Photo": "1.webp",
		"Place": "Набережная",
		"IsFavorite": true,
		"dateOfConnections": "2020-01-31"
	},
	{
		"Name": "Вика",
		"Age": 21,
		"Price": 9600,
		"Gender": "Ж",
		"Photo": "1.webp",
		"Place": "Йолка",
		"IsFavorite": true,
		"dateOfConnections": "2011-11-11"
	},
	{
		"Name": "Кристина",
		"Age": 17,
		"Price": 50,
		"Gender": "Ж",
		"Photo": "1.webp",
		"Place": "Планета",
		"IsFavorite": true,
		"dateOfConnections": "2019-10-12"
	},
	{
		"Name": "Анджелика",
		"Age": 16,
		"Price": 2000,
		"Gender": "Ж",
		"Photo": "1.webp",
		"Place": "Бульвар",
		"IsFavorite": true,
		"dateOfConnections": "2020-05-05"
	},
	{
		"Name": "Костя",
		"Age": 15,
		"Price": 1500,
		"Gender": "М",
		"Photo": "1.webp",
		"Place": "Бульвар",
		"IsFavorite": false,
		"dateOfConnections": "2022-01-25"
	},
	{
		"Name": "Вероника",
		"Age": 25,
		"Price": 5000,
		"Gender": "Ж",
		"Photo": "1.webp",
		"Place": "Набережная",
		"IsFavorite": true,
		"dateOfConnections": "2015-01-12"
	},
	{
		"Name": "Савелий",
		"Age": 20,
		"Price": 1000,
		"Gender": "М",
		"Photo": "1.webp",
		"Place": "Пляж",
		"IsFavorite": false,
		"dateOfConnections": "2024-03-05"
	},
	{
		"Name": "Алексндр",
		"Age": 39,
		"Price": 1500,
		"Gender": "М",
		"Photo": "1.webp",
		"Place": "ЙОТК",
		"IsFavorite": false,
		"dateOfConnections": "2023-04-20"
	},
	{
		"Name": "Евгений",
		"Age": 18,
		"Price": 500,
		"Gender": "М",
		"Photo": "1.webp",
		"Place": "Медведево",
		"IsFavorite": false,
		"dateOfConnections": "2016-09-26"
	},
	{
		"Name": "Давид",
		"Age": 18,
		"Price": 2500,
		"Gender": "М",
		"Photo": "1.webp",
		"Place": "Ремзавод",
		"IsFavorite": false,
		"dateOfConnections": "2020-10-01"
	}
]
```
![](./img/2.jpg)