【发布时间】:2012-09-13 11:54:02
【问题描述】:
假设我有一个带有列表框和文本框的基本控件,其中列表框绑定到对象集合并具有基本数据模板
<DockPanel LastChildFill="True">
<TextBlock DockPanel.Dock="Top">Book name</TextBlock>
<TextBox x:Name="bookNameTextBox" DockPanel.Dock="Top" />
<TextBlock DockPanel.Dock="Top">Authors</TextBlock>
<ListBox ItemsSource="{Binding Authors}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DockPanel>
public class Author : INotifyPropertyChanged
{
public string Name { get; set; }
public ObservableCollection<Book> Books { get; }
}
public class Book : INotifyPropertyChanged
{
public string Name { get; }
}
我想要做的是改变列表框中项目的颜色,具体取决于该作者是否有任何与提供的名称匹配的书籍,例如
Colour = author.Books.Any(b => b.Name.StartsWith(bookNameTextBox.Text)) ? Red : Black;
我最初认为我可以使用 MultiBinding 和转换器来执行此操作,但是我无法弄清楚如何在将项目添加到书籍集合中/从书籍集合中删除时更新绑定,或者当他的名称时书改了。
我怎样才能做到这一点,以使颜色能够正确更新以响应可能影响我的逻辑的所有各种变化?例如
- 任何书籍的名称发生变化
- 正在从收藏中添加和删除图书
-
bookNameTextBox文本框中的文本发生变化
我的 MultiBinding 看起来像这样
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource MyConverter}">
<Binding Path="Books" />
<Binding Path="Text" ElementName="bookNameTextBox" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Foreground" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
我的转换器(实现IMultiValueConverter)看起来像这样
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var text = (string)values.First(v => v is string);
var books = (IEnumerable<Book>)values.First(v => v is IEnumerable<Book>);
return books.Any(b => b.Name.StartsWith(text));
}
但是,如果我随后修改任何书籍,或添加任何书籍,列表项的文本颜色将不会更新,直到绑定以某种方式刷新。
【问题讨论】:
-
你是如何尝试使用 MultiBinding 的?
-
@MiklósBalogh 我已经更新了问题
-
我认为您将需要迭代作者并在名称上调用 NotifyPropertyChanged。
标签: c# wpf data-binding collections