[英]WPF. Binding inside listbox itemtemplate to ObservableCollection source. Source PropertyChanged is ignored
我正在尝试创建一个显示格式化文本的列表框。 我希望能够从代码更改格式。
为了显示格式化文本,我选择了 TextBlock 并打算使用 TextBlock.Inlines 集合进行格式化。 TextBlock.Inlines 不可绑定,因此我创建了从 TextBlock 派生的新 class BindableTextBlock 。 这个 class 有一个依赖属性InlineList ,我试图将其绑定到Model 中的 InlinesColl ObservableCollection。
问题是InlinesColl中的更改不会将 PropertyChanged 事件通知我的InlineList 。 绑定仅在BindableTextBlock object 创建时运行一次,此后便不再运行。
任何想法为什么?
XAML:
<ListBox x:Name="PART_lb" VerticalAlignment="Stretch" ItemsSource="{Binding ItemColl}"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto" >
<ListBox.ItemTemplate>
<DataTemplate>
<local:BindableTextBlock InlineList="{Binding Path=InlinesColl}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
可绑定文本块 class:
public class BindableTextBlock : TextBlock
{
public ObservableCollection<Inline> InlineList
{
get { return (ObservableCollection<Inline>)GetValue(InlineListProperty); }
set { SetValue(InlineListProperty, value); }
}
public static readonly DependencyProperty InlineListProperty =
DependencyProperty.Register("InlineList", typeof(ObservableCollection<Inline>), typeof(BindableTextBlock), new UIPropertyMetadata(null, OnPropertyChanged));
private static void OnPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
BindableTextBlock textBlock = (BindableTextBlock)sender;
textBlock.Inlines.Clear();
textBlock.Inlines.AddRange((ObservableCollection<Inline>)e.NewValue);
}
}
Model class
public class TextBlockModel
{
ObservableCollection<Inline> _inlinesColl = new ObservableCollection<Inline>();
public ObservableCollection<Inline> InlinesColl
{
get { return _inlinesColl; }
set {_inlinesColl = value; }
}
}
带有 ListBox ItemSource 集合的 ViewModel
ObservableCollection<TextBlockModel> _itemColl = new ObservableCollection<TextBlockModel>();
public ObservableCollection<TextBlockModel> ItemColl
{
get { return _itemColl; }
set { _itemColl = value; }
}
在这里测试项目
在你的情况下 - 你没有处理集合中的项目添加\删除的情况
需要 go 并在分配新集合时订阅 CollectionChanged。
public class BindableTextBlock : TextBlock
{
static int Cntr = 0;
public BindableTextBlock()
{
Console.WriteLine("BindableTextBlock constructor " + Cntr);
Cntr++;
}
public ObservableCollection<Inline> InlineList
{
get { return (ObservableCollection<Inline>)GetValue(InlineListProperty); }
set { SetValue(InlineListProperty, value); }
}
public static readonly DependencyProperty InlineListProperty =
DependencyProperty.Register("InlineList", typeof(ObservableCollection<Inline>), typeof(BindableTextBlock), new UIPropertyMetadata(null, OnPropertyChanged));
private static void OnPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
BindableTextBlock textBlock = (BindableTextBlock)sender;
// subscribe to collection changed
textBlock.UpdateInlineListSource((ObservableCollection < Inline > )e.OldValue, (ObservableCollection < Inline > )e.NewValue);
}
public void UpdateInlineListSource(ObservableCollection<Inline> oldCollection, ObservableCollection<Inline> newCollection)
{
if (oldCollection!=null)
oldCollection.CollectionChanged -= OnCollectionChanged;
if (newCollection != null)
{
newCollection.CollectionChanged += OnCollectionChanged;
OnCollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
OnCollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, newCollection));
}
}
private void OnCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
var newItems = e.NewItems?.Cast<Inline>()?.ToList() ?? new List<Inline>();
var oldItems = e.OldItems?.Cast<Inline>()?.ToList() ?? new List<Inline>();
// changed source
if (e.Action==NotifyCollectionChangedAction.Reset)
this.Inlines.Clear();
foreach (var itemForDelete in oldItems)
{
if (this.Inlines.Contains(itemForDelete))
this.Inlines.Remove(itemForDelete);
}
foreach (var itemsForAdd in newItems)
{
this.Inlines.Add(itemsForAdd);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.