Есть некий UserControl. У него есть свойство зависимостей ItemsProperty типа IList<string> (да да, именно строго типизированный лист). К этому свойству можно биндиться извне и, к тому же, сам контрол использует это свойство для отображения. Но при изменении коллекции как то так Items.Add("asd") в отображении ничего не меняется. Это логично, но как сказать отображению, что коллекция изменилась?
Теперь что я пытался с этим поделать.
Я пытался сделать ItemsProperty типа ObservableCollection<string>. Но при использовании контрола я не могу прибиндить ему свойство типа List<string> по понятным причинам.
Я пытался вызывать DependencyObject.OnPropertyChanged, но ничего не получилось.
Я пытался в xaml.cs контрола реализовать INotifyPropertyChanged и породить событие PropertyChanged для свойства Items
Так как же поступить?
Не знаю насколько сильно это вам поможет, но т.к. в большинстве случаев в качестве источника данных выступает ObservableCollection<T>, можем этим воспользоваться, поэтому делаем следующее:
1) В пользовательском контроле создаем DP.
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource",
typeof(IEnumerable<object>),
typeof(MyUserControl),
new PropertyMetadatadefault(IEnumerable<object>)));
public IEnumerable<object> ItemsSource
{
get
{
return (IEnumerable<object>)GetValue(ItemsSourceProperty);
}
set
{
SetValue(ItemsSourceProperty, value);
}
}
2) В конструкторе контролла подписываемся на изменение значения вашего DP.
public MyUserControl()
{
InitializeComponent();
var dp = DependencyPropertyDescriptor.FromProperty(ItemsSourceProperty, typeof(MyUserControl));
dp?.AddValueChanged(this, Handler);
}
3) В обработчике на изменение DP приводим ваше свойство к INotifyCollectionChangedи подписываемся на уведомления об изменении коллекции.
private void Handler(object sender, EventArgs eventArgs)
{
var nc = ItemsSource as INotifyCollectionChanged;
if (nc != null)
nc.CollectionChanged += OnCollectionChanged;
}
4) Далее реализуем вашу логику, реагирующую на изменения коллекции:
private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
// Ваша логика на реакцию об изменении свойства
}
Все целиком:
public partial class MyUserControl : UserControl
{
public MyUserControl()
{
InitializeComponent();
var dp = DependencyPropertyDescriptor.FromProperty(ItemsSourceProperty, typeof(MyUserControl));
dp?.AddValueChanged(this, Handler);
}
private void Handler(object sender, EventArgs eventArgs)
{
var nc = ItemsSource as INotifyCollectionChanged;
if (nc != null)
nc.CollectionChanged += OnCollectionChanged;
}
private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
// Ваш код
}
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register(
"ItemsSource",
typeof(IEnumerable<object>),
typeof(MyUserControl),
new PropertyMetadata(default(IEnumerable<object>)));
public IEnumerable<object> ItemsSource
{
get
{
return (IEnumerable<object>)GetValue(ItemsSourceProperty);
}
set
{
SetValue(ItemsSourceProperty, value);
}
}
}
Как развивать веб-проекты в 2026 году: технологии, контент E-E-A-T и факторы доверия
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники