I am new to wpf and aside from the reading of 'WPF unleashed', I try to write a little program, it gives me a direction to go to. So here is my problem : I want to manage my books, at home, with a little library program. Each book is stored in a Book class instance. thus, This Book class contains all the informations of the book, and among them its keywords, which is a ObservableCollection in a 'Keywords' property:
public ObservableCollection<string> Keywords
{
get => _keywords;
set
{
_keywords = value;
OnPropertyChanged("Keywords");
}
}
(_keywords is a string).
What I want is to display a textBox and a combobox which show related piece of informations: the textBox show all the Keywords of the selected book, and the combobox show a list of checkboxes, it is filled by the list of all the Keywords in all the books of the library, listed once (duplicate removed) and each checkbox is checked if the keyword is present in the listbox of the selected book. I will try to explain it differently : each book contains a list of all its keywords. The combobox contains all the existing keywords (of all the books) and those related to the selected book are checked : it allows me 2 ways to add/edit/remove keywords : with the textbox, or by checking/unchecking the checkBoxes.
Back to my problem : how can I code this, using a maximum of databinding? For the textbox, I see no problem : I will create a property in 'Book' say 'KeywordsForTextbox' with only a getter returning the keywords collection items merged with the appropriate separation character. then, using a dataContext pointed to the selectedBook, the text property of the textbox is bound to KeywordsForTextbox. I would rather not considering the textbox edition for now.
But for the combobox, there are 2 things to bind: 1/ the list of all the keywords. I can put in my BookManagement class (which ... manages the Book class) a property whose getter will return the list of all the keywords (via link). 2/ each ComboboxItem will be edited in XAML but how to implement the behavior of setting it as checked/unchecked if the given keyword(got by using the property ItemSource of the checkbox to the Keyword property of the Book instance) is contained in the selectedItem.Keywords ?
more shortly : how to bind the checked property of a CheckBoxItem to the presence of this string in listView's selectedItem.Keywords (a list of strings)?
I apologize for the messy aspect of my question!
thank you.
EDIT
Well, I managed to write all the stuff, it builds and run, but there is a problem; in fact in the combobox, the itemsSource was written like this:
ItemsSource="{Binding Source={StaticResource AllBooks}}"
and AllBooks is a resource:
<ObjectDataProvider
x:Key="AllBooks"
MethodName="listOfAllKeywords"
ObjectType="{x:Type mangmt:BookManagement}" />
here is the method:
public static ObservableCollection<string> listOfAllKeywords()
{
if (App.Books != null)
{
IEnumerable<string> kws = App.Books.SelectMany(book => book.Keywords).Distinct();
return new ObservableCollection<string>(kws);
}
else return new ObservableCollection<string>();
}
When I run my program, the window is displayed normally, but if I click on a book to display it, and if I click on the combobox, at the second click I get an exception : System.InvalidCastException : 'Impossible d'effectuer un cast d'un objet de type 'MS.Internal.NamedObject' en type 'System.String'.' which saying the cast is impossible. I saw in the debugging that in the multibinding, the seconf parameter is null(anyway it seems not very relevant because the exception is caused by the first parameter, but yet it's annoying).
I recall you my multibinding:
<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}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Width="200">
<MultiBinding Converter="{StaticResource TextInListTrueFalseConverter}" >
<Binding Path="KeywordsForTextbox"></Binding>
<Binding RelativeSource="{RelativeSource Self}" Path="Content"></Binding>
</MultiBinding>
</CheckBox>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
here is KeywordsForTextBox:
public string KeywordsForTextbox
{
get { return string.Join(",", _keywords); }
}
(it's in the Book class) is the first binding (of the multibinding) wrong?why?
thank you.
EDIT 2 I created a new post because this one is too messy(too much text in my question) and the area of the possible causes is much restricted as I saw this was a dependencyProperty problem. here is the link : here in stack overflow