Вывести информацию из базы данных в listview или другим способом (WPF)
Cтолкнулся с проблемой 2 дня назад с выводом базы данных MySQL "phpmyadmin" в приложении. В базе данных на локальном сервере храниться text и id, photo в формате BIN-BLOB. В долгих поисках вывода такого рода информации в GridView я натыкался на все возможные варианты, которые к сожалению мне не подходили. Остановившись на этом варианте я пишу сюда.
MySqlConnection conn = new MySqlConnection("server=localhost;port=3306;username=root;password=root;database=couseuiop");
conn.Open();
string cmd = "SELECT * FROM news"; // Из какой таблицы нужен вывод
MySqlCommand createCommand = new MySqlCommand(cmd, conn);
createCommand.ExecuteNonQuery();
MySqlDataAdapter dataAdp = new MySqlDataAdapter(createCommand);
DataTable dt = new DataTable("news"); // В скобках указываем название таблицы
dataAdp.Fill(dt);
StudentsGrid.ItemsSource = dt.DefaultView; // Сам вывод
conn.Close();
Код в XAML:
Grid Background="AliceBlue">
<DataGrid HorizontalAlignment="Left" Height="400" Margin="10,10,0,0" VerticalAlignment="Top" Width="642" AutoGenerateColumns="True" Name="StudentsGrid">
</DataGrid>
</Grid>
Как сделать так, чтобы подобного рода результат который я на данный момент имею:
Был хотя бы приблизительно в таком варианте :
Есть вариант кода декодирования изображения в формате bin-blob (png)
MySqlCommand command_image = new MySqlCommand("SELECT * FROM `news` WHERE id = 535", dataBase.GetConnection());
dataBase.openConBd();
MySqlDataReader reader_image = command_image.ExecuteReader();
while (reader_image.Read())
{
byte[] imageBytes = (byte[])reader_image[1];
MemoryStream ms = new MemoryStream();
ms.Write(imageBytes, 0, imageBytes.Length);
BitmapImage bmp = new BitmapImage();
bmp.BeginInit();
bmp.StreamSource = ms;
bmp.EndInit();
imageAdd.Source = bmp;
}
dataBase.CloseConBd();
Буду очень рад в любой оказанной помощи. Я только начал изучать WPF & базы данных, многие описанные вами алгоритмы могут оказаться сложными и хотелось бы попросить описать возможные варианты решение более доступным языком, для меня и других пользователей) Заранее спасибо
Ответы (1 шт):
Image может биндиться прямо к массиву байт, преобразование в картинку произойдет автоматически. Чтобы сделать то что вам надо, не нужна DataGrid.
<ItemsControl>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Image Source="{Binding img}"/>
<TextBlock Text="{Binding text}" Grid.Column="1"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Если нужно выбирать элемент из коллеции, то подойдет ListBox, просто замените ItemsControl на ListBox и все продолжит работать. Если выбор не нужен, а нужна только прокрутка, то можно ItemsControl снаружи завернуть в ScrollViewer.
Кстати, привязки данных можно делать и на верхнем уровне, а не только внутри коллекций.
Допустим, вы весь код пишете в классе окна и про MVVM не в курсе, тогда нужно изменить класс окна вот так
public partial class MyWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private DataTable _items; // не используйте _items в других местах кода
public DataTable Items // вместо этого используйте именно Items
{
get => _items;
set
{
_items = value;
PropertyChanged?.Invoke(new PropertyChangedEventArgs(nameof(Items)));
}
}
public MyWindow()
{
InitializeComponent();
DataContext = this;
}
}
А в разметке написать вот так
<ItemsControl ItemsSource="{Binding Items}">
Тогда в вашем методе чтения из базы достаточно будет написать вот так.
Items = dt;
При чем в коде вы можете переприсваивать Items где угодно и сколько угодно раз. ItemsControl сам подхватит изменения.
Всё, никакой возни с битмапами и прочими мучениями в C# с интерфейсом не требуется. Учитесь пользоваться привязками данных, WPF заточен под них и многое умееет делать сам.