【发布时间】:2018-11-10 13:51:41
【问题描述】:
我有一个列表视图,其中包含“书”实例的项目,当我单击一本书时,组合框应显示其关键字;实际上它有点棘手:组合框包含所有书籍的所有关键字的列表(重复删除)(组合框项是复选框),并且选中了所选书籍的关键字。 这是多重绑定:
<ComboBox
x:Name="cbb_Keywords"
Grid.Column="2"
Width="300"
Margin="5,0,0,0"
HorizontalAlignment="Left"
ItemsSource="{Binding Source={StaticResource AllBooks}}"
DataContext="{Binding ElementName=listBoxBooks,Path=SelectedItem,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Width="200">
<CheckBox.IsChecked>
<MultiBinding Converter="{StaticResource TextInListTrueFalseConverter}" >
<Binding Path="KeywordsForTextbox"></Binding>
<Binding RelativeSource="{RelativeSource Self}" Path="Content"></Binding>
</MultiBinding>
</CheckBox.IsChecked>
</CheckBox>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
当我运行我的程序时,当我点击一本书时似乎没问题,但当我点击组合框时出现异常:不可能从“MS.Internal.NamedObject”类型转换为“System.String”类型。我看到 value[0] 是 UnsetValue。
在调试时,当我使用间谍跟踪 WpfApp1.App.Books[0].KeywordsForTextbox 的值时,它给了我很好的值(一个字符串,它是 Book[0] 的关键字列表。也许问题来自 listboxBooks.SelectedItem.KeywordsForTextBox?我无法在 VS 中窥探“listboxBooks”的值。
一些相关内容... MainWindow的构造函数的开头:
public MainWindow()
{
InitializeComponent();
listBoxBooks.ItemsSource = App.Books;
转换器的convert方法:
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var check = false;
if ((values != null && values.Length == 2))
{
string listString = (string)values[0];
string wordToFind = (string) values[1];
if ((listString != null))
{
List<string> keywordsList = listString.Split(',').ToList();
if (keywordsList.Contains(wordToFind)) check = true;
}
}
return check;
}
KeywordsForTextbox 方法:
public string KeywordsForTextbox
{
get { return string.Join(",", _keywords); }
}
最后是 AllBooks 的实现:(作为窗口资源)
<ObjectDataProvider
x:Key="AllBooks"
MethodName="listOfAllKeywords"
ObjectType="{x:Type mangmt:BookManagement}" />
谢谢。
【问题讨论】:
-
首先,我假设您的 TextInListTrueFalseConverter 的 Convert 方法会引发异常。那么,是在将
values[0]转换为字符串时还是在将values[1]转换为时发生异常?我猜是后者(值来自<Binding RelativeSource="{RelativeSource Self}" Path="Content">)。我对项目对象如何与项目视觉关联的回忆有点生疏,但是如果您使用稍微不同的绑定会发生什么(参考项目视觉本身的 DataContext):<Binding RelativeSource="{RelativeSource Self}" Path="DataContext">? -
否,value[0] 是抛出异常的那个,值是 DependencyProperty.Unset,一个占位符,表示绑定有问题。但是为什么,这是我的问题。
-
啊,抱歉。我错过了您提到 value[0] 的句子...请注意,您的 ComboBox 项目来源是
AllBooks。现在,除了BookManagement类型之外,不知道 AllBooks 到底是什么(我想是一些带有某种类型条目的集合)。但是,显然,组合框项将是此 BookManagement 集合中的元素。因此 KeywordsForTextbox 绑定将尝试在 BookManagement 集合的元素中查找 KeywordsForTextbox。 (1/2) -
我注意到您只与
App.Books一起谈论KeywordsForTextbox,但从不与AllBooks一起谈论。如果 KeywordsForTextbox 属性仅由 listBoxBooks.SelectedItem 中的对象提供,则不能只设置组合框的 DataContext 并完成它(因为项目模板中的绑定默认绑定相应项目视觉对象的 DataContext,它是 Combobox.ItemsSource 中的项目对象)。如果您需要项目模板绑定到相应项目对象“外部”的数据,则需要指定绑定源(2/2) -
标签: c# wpf data-binding