gpt4 book ai didi

c# - 如果 ObservableCollection,绑定(bind)到文本框的列表将不会更新

转载 作者:太空宇宙 更新时间:2023-11-03 12:47:42 24 4
gpt4 key购买 nike

我正在 WPF 中创建自定义控件。我绑定(bind)一个List<IMyInterface>dependency property .这又再次绑定(bind)到 ListBox按预期显示所有项目。

我现在想将此列表中的 1 项绑定(bind)到 Textblock ,所以我将整个列表绑定(bind)到 textblock .我有一个 converter在此提取我想要的单个项目。

它运行良好,但出于一些原因,我想使用 ObservableCollection而不是 List

奇怪的是,当我更改 ObservabaleCollection 中的值时在运行时,该值显示在 ListBox 中(成功)但不在我的textblock . converter甚至没有被击中!

    public MainWindow()
{
InitializeComponent();
this.DataContext = this;
this.Errors = new ObservableCollection<IEventDetail>();
this.Errors.CollectionChanged += Errors_CollectionChanged;
var bw = new BackgroundWorker();
bw.DoWork += ((o, e) =>
{
System.Threading.Thread.Sleep(1500);
Dispatcher.Invoke(() =>
{
this.Errors.Add(new MyEvents("example of some detail", "Failed title"));
});

System.Threading.Thread.Sleep(2500);

Dispatcher.Invoke(() =>
{
this.Errors.Add(new MyEvents("Another example", "Failed title 2"));
});
});
bw.RunWorkerAsync();//background worker for testing/debugging only
}

private void Errors_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
OnPropertyChanged("Errors");
}

private ObservableCollection<IEventDetail> _errors;
public ObservableCollection<IEventDetail> Errors
{
get
{
return this._errors;
}
set
{
this._errors = value;
OnPropertyChanged("Errors");
}
}


public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged == null)
return;

PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

xaml 很简单

 <local:Notify Events="{Binding Errors}" DockPanel.Dock="Right"/>

如您所见,我已尝试使用 CollectionChanged事件然后强制触发 INotifyPropertyChanged , 但它在我的 Converter 中触发然而ListBox正在更新(所以我知道绑定(bind)没问题)

这是 UserControls xaml

 <TextBlock Text="{Binding Path=Events, RelativeSource={RelativeSource AncestorLevel=1, AncestorType=UserControl}, Mode=Default, Converter={StaticResource MostRecentConverter}}" Grid.Row="0" />

<ListBox ItemsSource="{Binding Path=Events, RelativeSource={RelativeSource AncestorLevel=1,AncestorType=UserControl}, Mode=Default}" Grid.Row="1">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding EventTitle}" Style="{StaticResource txtBckRed}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

我还需要做其他事情吗?

最佳答案

如评论中所述TextBlock只绑定(bind)到Events属性更改(不是它的项目),因此除非创建新的集合实例,否则它不会触发。对 INotifyCollectionChanged 作出 react 是 ItemsSource 的特征属性(property)。

解决方案一

暂时保留所有内容,只需提供 TextBlock一些名字

<TextBlock Text="{Binding ...}" x:Name="myTextBlock"/>

并订阅CollectionChanged你里面的事件UserControl您手动强制绑定(bind)目标更新的地方

public partial class MyUserControl : UserControl
{
public static readonly DependencyProperty EventsProperty =
DependencyProperty.Register("Events",
typeof(IEnumerable),
typeof(MyUserControl),
new PropertyMetadata(EventsPropertyChanged));

private static void EventsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((MyUserControl)d).EventsPropertyChanged(e);
}

private void EventsPropertyChanged(DependencyPropertyChangedEventArgs args)
{
var newCollection = args.NewValue as INotifyCollectionChanged;
if (newCollection != null)
newCollection.CollectionChanged += (s, e) => myTextBlock.GetBindingExpression(TextBlock.TextProperty).UpdateTarget();
}

public IEnumerable Events
{
get { return (IEnumerable)GetValue(EventsProperty); }
set { SetValue(EventsProperty, value); }
}

}

方案二

创建你自己的集合类继承自ObservableCollection<T>具有可以执行您的转换器所做的自定义属性

public class MyObservableCollection<T> : ObservableCollection<T>
{
private string _convertedText;

protected override void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
base.OnCollectionChanged(e);
this.ConvertedText = ...; // <- do here what your IValueConverter does
}

public string ConvertedText
{
get { return _convertedText; }
private set
{
_convertedText = value;
OnPropertyChanged(new PropertyChangedEventArgs("ConvertedText"));
}
}
}

并绑定(bind)TextBlock.TextEvents.ConvertedText属性代替,不需要转换器

关于c# - 如果 ObservableCollection,绑定(bind)到文本框的列表将不会更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36661607/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com