Я получил класс UserCache, имеющий свойство Current. Объект этого класса помещается в класс фасада ConnectedUserCache, который также имеет свойство Current.
MainWindow.xaml
Код: Выделить всё
[...]
[...]
Vorname:
Nachname:
Telefon:
[...]
Код: Выделить всё
public partial class MainWindow : Window
{
private ConnectedUserCache _cache = new ConnectedUserCache();
public MainWindow()
{
InitializeComponent();
DataContext = _cache;
// Otherwise DataGrid would not be filled at the beginning
_cache.RefreshAsync();
ReloadDataGrid(_cache);
}
private void ReloadDataGrid(ConnectedUserCache? cache)
{
UserDataGrid.ItemsSource = null;
UserDataGrid.ItemsSource = cache.UsersShown;
}
private void Button_SeachUserInCache_Click(object sender, RoutedEventArgs e)
{
var cache = DataContext as ConnectedUserCache;
if (cache == null) return;
cache.SearchCurrentUser();
// Reload datasource of datagrid
UserDataGrid.ItemsSource = null;
UserDataGrid.ItemsSource = cache.UsersShown;
}
[...]
Код: Выделить всё
using System.Collections.ObjectModel;
using System.ComponentModel;
using UserWpfClient.Http;
using UserWpfClient.LocalData;
namespace UserWpfClient
{
internal class ConnectedUserCache : INotifyPropertyChanged
{
private UserCache _userCache = new UserCache();
private HttpUserClient _userClient = new HttpUserClient();
public ConnectedUserCache() {}
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
[...]
public event PropertyChangedEventHandler? PropertyChanged;
public UserModelView Current
{
get { return _userCache.Current; }
set
{
_userCache.Current = value;
OnPropertyChanged(nameof(Current));
}
}
[...]
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
[...]
Код: Выделить всё
public class UserCache : INotifyPropertyChanged
{
private Collection _allUsers = new Collection();
private UserModelView _current = new UserModelView();
public event PropertyChangedEventHandler? PropertyChanged;
public ObservableCollection UsersShown { get; set; } = [];
public UserModelView Current
{
get => _current;
set
{
_current = value;
OnPropertyChanged(nameof(Current));
}
}
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private bool GetSomeUsersByFirstName()
{
var result = new List();
foreach (var item in _allUsers)
{
if (item.FirstName == Current.FirstName) result.Add(item);
}
UsersShown = new ObservableCollection(result);
// Feedback to the user, for what we have been looking for
Current = new UserModelView()
{
FirstName = Current.FirstName,
LastName = string.Empty,
PhoneNumber = string.Empty
};
return UsersShown.Any();
}
public bool Refresh()
{
UsersShown = new ObservableCollection(_allUsers);
Current = new UserModelView();
return UsersShown.Any();
}
[...]
Код: Выделить всё
using System.ComponentModel;
using UserWpfClient.Attributes;
namespace UserWpfClient.LocalData
{
public class UserModelView : INotifyPropertyChanged
{
private string _firstName = string.Empty;
private string _lastName = string.Empty;
private string _phoneNumber = string.Empty;
public event PropertyChangedEventHandler? PropertyChanged;
[ColumnName("Vorname")]
public string FirstName
{
get => _firstName ?? string.Empty;
set
{
_firstName = value;
OnPropertyChanged(nameof(FirstName));
}
}
[ColumnName("Nachname")]
public string LastName
{
get => _lastName ?? string.Empty;
set
{
_lastName = value;
OnPropertyChanged(nameof(LastName));
}
}
[ColumnName("Telefon")]
public string PhoneNumber
{
get => _phoneNumber ?? string.Empty;
set
{
_phoneNumber = value;
OnPropertyChanged(nameof(PhoneNumber));
}
}
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
и двусторонняя привязка Wpf в списке.
И, как вы можете видеть, я изменил там классы (UserCache , ConnectedUserCache и UserModelView) соответственно.
Далее я буду следовать этому: https://learn.microsoft.com/en-us/dotne ... leproperty Но как это уменьшает количество шаблонов, я думаю, что мне все еще нужно понять основную причину моей проблемы, что означает гораздо лучшее понимание WPF и его событий.
MainWindow.xaml
Я предпринял несколько попыток с Mode=TwoWay и/или UpdateSourceTrigger=PropertyChanged.
UserCache.cs
Я попробовал это с INotifyPropertyChanged и без него.
Ожидание и то, что происходит на самом деле:
Я ожидаю, что если эти текстовые поля получили контент, это связанное свойство «Текущий» также имеет такое же содержимое, как и свойство «Текущий» внутри — и все это тоже наоборот.
Но произойдет следующее: если я напишите что-нибудь в одно из этих текстовых полей во время выполнения от имени пользователя, например. начните фильтровать пользователей по сетке данных (с привязкой к кешу), все работает нормально. Затем, после повторного отображения всех пользователей (что работает нормально) и ввода текстового поля по-прежнему отображается, когда я снова начинаю фильтрацию, оно должно работать так же, как и раньше, поскольку использует тот же код.
Но он снова не фильтрует. Мне нужно снова переписать текстовое поле. Таким образом, похоже, что границе нужен триггер обновления или, другими словами, граница кажется потерянной в этот конкретный момент.
Вопросы:
Итак , когда я записываю эти строки, мне интересно, не в том ли направлении ищу. Это проблема привязки? Или проблема кроется где-то в другом? Какие классы должны иметь INotifyChanged в моем примере?
Мой следующий шаг:
Если вы дадите мне несколько минут, в течение следующих дней я будут ли мои git-репозитории (WPF-Client и Backend-Service) общедоступными. Но, пожалуйста, не ждите чего-то идеального. Это всего лишь исследование для обучения.
Подробнее здесь: https://stackoverflow.com/questions/785 ... und-object
Мобильная версия