#wpf #data-binding
#wpf #привязка данных
Вопрос:
Моя цель — привязать к набору объектов в WPF. Сначала я попытался использовать дженерики, но у меня это ужасно не получилось. Поскольку я не могу привести общие свойства к интерфейсам INotifyProperty, чтобы подключить changedevent.
Итак, я придумал этот класс для использования в качестве объекта в моем списке привязок. (Да, мне нужны они, чтобы уведомлять меня, когда изменяется объект в списке). Итак, мне нужно ваше мнение, улучшения в моем коде.
public class GPair : ObservableObject
{
public GPair()
{
}
private ObservableObject _first;
public ObservableObject First
{
get
{
return this._first;
}
set
{
this._first = value;
((ObservableObject)value).PropertyChanged =new PropertyChangedEventHandler(First_PropertyChanged);
RaisePropertyChanged("First");
}
}
private ObservableObject _second;
public ObservableObject Second
{
get
{
return this._second;
}
set
{
this._second = value;
((ObservableObject)value).PropertyChanged = new PropertyChangedEventHandler(Second_PropertyChanged);
RaisePropertyChanged("Second");
}
}
private void First_PropertyChanged(object sender, PropertyChangedEventArgs args)
{
RaisePropertyChanged("First");
}
private void Second_PropertyChanged(object sender, PropertyChangedEventArgs args)
{
RaisePropertyChanged("Second");
}
}
ObservableObject — это просто вспомогательный класс, который реализует INotifyPropertyChanged.
Этот фрагмент кода позволяет мне связать два объекта в привязке… Сама привязка будет выглядеть следующим образом:
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=First.ObjectPropertie}" />
<TextBlock Text="{Binding Path=Second.ObjectPropertie}" />
</StackPanel>
Есть мнения или улучшения??
С уважением!
Комментарии:
1. И в вашей версии это также сделано неправильно. 1) У вас нет возможности отказаться от подписки на событие, поэтому все предыдущие значения останутся в памяти до завершения работы приложения. 2) Также нет проверки на null — из-за этого при присвоении null будет выдаваться исключение. 3) Приведение значения к ObservableObject также является бессмыслицей. значение уже этого типа.
Ответ №1:
Я не совсем понимаю, чего вы пытаетесь достичь, но класс GPair выглядит странно
Как насчет чего-то подобного?
public class ObservablePair : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private MyObject m_First;
public MyObject First
{
get { return m_First; }
set
{
m_First = value;
OnPropertyChanged("First");
}
}
private MyObject m_Second;
public MyObject Second
{
get { return m_Second; }
set
{
m_Second = value;
OnPropertyChanged("Second");
}
}
public void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new
PropertyChangedEventArgs(propertyName)); ;
}
}
HTH
Комментарии:
1. Например, я получил информацию от 2 объектов, которые я хочу показать в одном списке / datagrid / etc… любой элемент управления, который способен отображать списки. Но я могу установить datacontext этого элемента управления только на 1 объект. Итак, мне нужен своего рода «Кортеж», но с изменяемыми данными и реализованным INotifyPropertyChanged. Ваш код почти точно такой же, как мой. В моем классе ObservableObject есть только материал PropertyChanged, от которого я наследую. Но, глядя на ваш ответ .. кажется, я на правильном пути .. 🙂 приветствия 🙂
Ответ №2:
Вот мой взгляд на ответ:
public class ObservablePair<T1, T2> : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private T1 _item1;
public T1 Item1
{
get => _item1;
set => OnPropertyChanged(nameof(Item1), _item1 = value);
}
private T2 _item2;
public T2 Item2
{
get => _item2;
set => OnPropertyChanged(nameof(Item2), _item2 = value);
}
public void OnPropertyChanged<T>(string propertyName, T _)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}