Alalonia UI привязка данных к xaml
Пытаюсь из бд вывести всех пользователей
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Messenger.MainWindow"
Width="800" Height="600" Title="Messenger">
<Grid ColumnDefinitions="200,*,Auto" RowDefinitions="*">
<!-- Список пользователей -->
<ListBox Name="UserList" Grid.Column="0" SelectionChanged="UserSelected">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding username}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<!-- Сообщения -->
<ScrollViewer Grid.Column="1">
<StackPanel x:Name="MessagesPanel" />
</ScrollViewer>
<!-- Ввод сообщения -->
<Grid Grid.Column="1" VerticalAlignment="Bottom">
<TextBox x:Name="MessageInput" Width="600" Height="30" />
<Button x:Name="SendButton" Content="Send" Click="SendMessage" HorizontalAlignment="Right"/>
</Grid>
</Grid>
</Window>
using Avalonia.Controls;
using Avalonia.Interactivity;
using System.Collections.ObjectModel;
using System.Linq;
using Messenger.Data;
using MsBox.Avalonia;
namespace Messenger
{
public partial class MainWindow : Window
{
private ObservableCollection<User> Users { get; set; } = new ObservableCollection<User>();
private User SelectedUser { get; set; }
private int CurrentUserId { get; set; }
public MainWindow(string username)
{
InitializeComponent();
// Установка текущего пользователя
using (var context = new AppDbContext())
{
var currentUser = context.users.FirstOrDefault(u => u.username == username);
if (currentUser == null)
{
throw new System.Exception("Пользователь не найден.");
}
CurrentUserId = currentUser.id;
// Загрузка списка других пользователей
var users = context.users.Where(u => u.id != CurrentUserId).ToList();
foreach (var user in users)
{
Users.Add(user);
}
}
// Инициализация компонентов UI
UserList.ItemsSource = Users;
UserList.SelectionChanged += UserSelected;
// Инициализация остальных компонентов UI
MessagesPanel = MessagesPanel ?? new StackPanel(); // Прямой доступ к MessagesPanel
// Прямой доступ к MessageInput
SendButton.Click += SendMessage; // Прямой доступ к SendButton
}
private void UserSelected(object? sender, SelectionChangedEventArgs e)
{
SelectedUser = (User)((ListBox)sender).SelectedItem;
if (SelectedUser != null)
{
LoadMessages();
}
}
private void LoadMessages()
{
MessagesPanel.Children.Clear();
using (var context = new AppDbContext())
{
var messages = context.messages
.Where(m => (m.senderid == CurrentUserId && m.receiverid == SelectedUser.id) ||
(m.senderid == SelectedUser.id && m.receiverid == CurrentUserId))
.AsEnumerable() // Принудительно выполняем запрос на клиенте
.OrderBy(m => m.timestamp) // Сортировка уже на клиенте
.ToList();
foreach (var message in messages)
{
AddMessageToChat(message.content, message.senderid == CurrentUserId);
}
}
}
private void SendMessage(object? sender, RoutedEventArgs e)
{
if (SelectedUser == null || string.IsNullOrWhiteSpace(MessageInput.Text))
return;
string messageContent = MessageInput.Text; // Получаем текст сообщения
AddMessageToChat(messageContent, true);
using (var context = new AppDbContext())
{
var message = new Message
{
senderid = CurrentUserId,
receiverid = SelectedUser.id,
content = messageContent // Убедитесь, что content не пустое
};
// Проверяем, что content действительно не пустое
if (string.IsNullOrWhiteSpace(message.content))
{
ShowMessage("Ошибка", "Сообщение не может быть пустым.");
return;
}
// Здесь может возникать ошибка, если content = NULL
context.messages.Add(message);
context.SaveChanges();
}
MessageInput.Text = string.Empty;
}
private void AddMessageToChat(string message, bool isCurrentUser)
{
var textBlock = new TextBlock
{
Text = message,
Margin = new Avalonia.Thickness(5),
Background = new Avalonia.Media.SolidColorBrush(
isCurrentUser ? Avalonia.Media.Colors.LightBlue : Avalonia.Media.Colors.LightGray
),
HorizontalAlignment = isCurrentUser ? Avalonia.Layout.HorizontalAlignment.Right : Avalonia.Layout.HorizontalAlignment.Left,
MaxWidth = 250,
TextWrapping = Avalonia.Media.TextWrapping.Wrap
};
MessagesPanel.Children.Add(textBlock);
}
private async void ShowMessage(string title, string message)
{
var messageBox = MessageBoxManager
.GetMessageBoxStandard(title, message);
var result = await messageBox.ShowAsync();
}
}
}
public class User
{
public int id { get; set; } // Идентификатор (PK)
public string username { get; set; } = string.Empty; // Имя пользователя
public string email { get; set; } = string.Empty; // Электронная почта
public string passwordhash { get; set; } = string.Empty; // Пароль
}
но вылетает ошибка
Unable to resolve property or method of name 'username' on type 'XamlX.TypeSystem.XamlPseudoType'., строка 10, позиция 17.
не могу понят в чем проблема может логики как то криво криво реализовал и так нельзя делать?
Ответы (1 шт):
Автор решения: Заурбек
→ Ссылка
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Messenger.MainWindow"
Width="800" Height="600" Title="Messenger"
xmlns:data="clr-namespace:Messenger.Data">
<Grid ColumnDefinitions="200,*,Auto" RowDefinitions="*">
<!-- Привязка ItemsSource через привязку к Users -->
<ListBox x:Name="UserList" Grid.Column="0" SelectionChanged="UserSelected" >
<ListBox.ItemTemplate>
<DataTemplate x:DataType="data:User">
<!-- Привязка конкретного свойства username -->
<TextBlock Text="{Binding username}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<!-- Сообщения -->
<ScrollViewer Grid.Column="1">
<StackPanel x:Name="MessagesPanel" />
</ScrollViewer>
<!-- Ввод сообщения -->
<Grid Grid.Column="1" VerticalAlignment="Bottom">
<TextBox x:Name="MessageInput" Width="600" Height="30" />
<Button x:Name="SendButton" Content="Send" Click="SendMessage" HorizontalAlignment="Right"/>
</Grid>
</Grid>
</Window>
указал путь на класс User, и заработало.
кому интересно - полный код:
using Avalonia.Controls;
using Avalonia.Interactivity;
using System.Collections.ObjectModel;
using System.Linq;
using Messenger.Data;
using MsBox.Avalonia;
using System.Collections.Generic;
namespace Messenger
{
public partial class MainWindow : Window
{
public ObservableCollection<User> Users { get; set; } = new ObservableCollection<User>();
private User SelectedUser { get; set; }
private int CurrentUserId { get; set; }
public MainWindow(string username)
{
InitializeComponent();
// Установка текущего пользователя
using (var context = new AppDbContext())
{
var currentUser = context.users.FirstOrDefault(u => u.username == username);
if (currentUser == null)
{
throw new System.Exception("Пользователь не найден.");
}
CurrentUserId = currentUser.id;
// Загрузка списка других пользователей
var users = context.users.Where(u => u.id != CurrentUserId).ToList();
foreach (var user in users)
{
Users.Add(user);
}
}
// Устанавливаем ItemsSource для UserList
DataContext = this; // Прямое связывание коллекции с ListBox
UserList.ItemsSource = Users;
// Инициализация компонентов UI
UserList.SelectionChanged += UserSelected;
MessagesPanel = MessagesPanel ?? new StackPanel();
SendButton.Click += SendMessage;
}
private void UserSelected(object? sender, SelectionChangedEventArgs e)
{
SelectedUser = (User)((ListBox)sender).SelectedItem;
if (SelectedUser != null)
{
LoadMessages();
}
}
private void LoadMessages()
{
MessagesPanel.Children.Clear();
using (var context = new AppDbContext())
{
var messages = context.messages
.Where(m => (m.senderid == CurrentUserId && m.receiverid == SelectedUser.id) ||
(m.senderid == SelectedUser.id && m.receiverid == CurrentUserId))
.AsEnumerable() // Принудительно выполняем запрос на клиенте
.OrderBy(m => m.timestamp) // Сортировка уже на клиенте
.ToList();
foreach (var message in messages)
{
AddMessageToChat(message.content, message.senderid == CurrentUserId);
}
}
}
private void SendMessage(object? sender, RoutedEventArgs e)
{
if (SelectedUser == null || string.IsNullOrWhiteSpace(MessageInput.Text))
return;
string messageContent = MessageInput.Text; // Получаем текст сообщения
AddMessageToChat(messageContent, true);
using (var context = new AppDbContext())
{
var message = new Message
{
senderid = CurrentUserId,
receiverid = SelectedUser.id,
content = messageContent // Убедитесь, что content не пустое
};
// Проверяем, что content действительно не пустое
if (string.IsNullOrWhiteSpace(message.content))
{
ShowMessage("Ошибка", "Сообщение не может быть пустым.");
return;
}
// Здесь может возникать ошибка, если content = NULL
context.messages.Add(message);
context.SaveChanges();
}
MessageInput.Text = string.Empty;
}
private void AddMessageToChat(string message, bool isCurrentUser)
{
var textBlock = new TextBlock
{
Text = message,
Margin = new Avalonia.Thickness(5),
Background = new Avalonia.Media.SolidColorBrush(
isCurrentUser ? Avalonia.Media.Colors.LightBlue : Avalonia.Media.Colors.LightGray
),
HorizontalAlignment = isCurrentUser ? Avalonia.Layout.HorizontalAlignment.Right : Avalonia.Layout.HorizontalAlignment.Left,
MaxWidth = 250,
TextWrapping = Avalonia.Media.TextWrapping.Wrap
};
MessagesPanel.Children.Add(textBlock);
}
private async void ShowMessage(string title, string message)
{
var messageBox = MessageBoxManager
.GetMessageBoxStandard(title, message);
var result = await messageBox.ShowAsync();
}
}
}