多重绑定中的DependencyProperty.unsetValue

时间:2018-11-10 13:51:41

标签: c# wpf data-binding

我有一个listView项是“ Book”实例,当我单击一本书时,组合框应显示其关键字;实际上,这有点棘手:组合框包含所有书籍(已删除重复项)的所有关键字的列表(comboboxItems为复选框),并且选中了所选书籍的所有关键词。 这是多重绑定:

<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;

转换器的转换方法:

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}" />

谢谢。

1 个答案:

答案 0 :(得分:1)

Multi的第一个绑定应该是到Books ListBox中的SelectedItem。我在适当的地方添加了<CheckBox.IsChecked>,并在CheckBox中添加了Content =“ {Binding}”:

                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <CheckBox Width="200" Content={Binding}>
                              <CheckBox.IsChecked>
                                <MultiBinding Converter="{StaticResource TextInListTrueFalseConverter}" >
                                    <Binding ElementName=listBoxBooks, Path=SelectedItem.KeywordsForTextbox"></Binding>
                                    <Binding RelativeSource="{RelativeSource Self}" Path="Content"></Binding>
                                </MultiBinding>
                              </CheckBox.IsChecked>
                            </CheckBox>
                        </StackPanel>
                    </DataTemplate>
                </ComboBox.ItemTemplate>

您还可能希望向IMultiValueConverter添加一些验证,以确保传递的值未设置为避免异常:VB中的If Not values(0) Is DependencyProperty.UnsetValue And Not values(1) Is DependencyProperty.UnsetValue Then

关于检查复选框的行为,我猜这是由于IMultiValueConverter的ConvertBack方法所致。您可以删除“引发异常”代码,并编写一种方法来将选中/未选中框的文本添加/删除到关键字列表中。