Я новичок в wpf, и, кроме прочтения «WPF unleashed», я пытаюсь написать небольшую программу, которая дает мне направление, по которому можно идти.
Итак, вот моя проблема: я хочу управлять своими книгами дома с помощью небольшой библиотечной программы. Каждая книга хранится в экземпляре класса Book. таким образом, класс This Book содержит всю информацию о книге, а также ее ключевые слова, которые представляют собой ObservableCollection в свойстве «Keywords»:
public ObservableCollection<string> Keywords
{
get => _keywords;
set
{
_keywords = value;
OnPropertyChanged("Keywords");
}
}
(_ ключевые слова - строка).
Мне нужно отобразить текстовое поле и поле со списком, которые показывают связанную часть информации: поле текста показывает все ключевые слова выбранной книги, а поле со списком показывает список флажков, он заполняется списком всех Ключевые слова во всех книгах библиотеки указаны один раз (дубликаты удалены), и каждый флажок отмечен, если ключевое слово присутствует в списке выбранной книги.
Я попытаюсь объяснить это по-разному: каждая книга содержит список всех своих ключевых слов. В комбинированном ящике содержатся все существующие ключевые слова (из всех книг), и те, которые относятся к выбранной книге, отмечены: это позволяет мне добавлять / редактировать / удалять ключевые слова двумя способами: с помощью текстового поля или установкой / снятием флажка.
Возвращаясь к моей проблеме: как я могу закодировать это, используя максимум привязки данных?
Для текстового поля я не вижу проблем: я создам свойство в «Книге», скажем «KeywordsForTextbox», с использованием только метода получения, возвращающего элементы коллекции ключевых слов, объединенные с соответствующим разделительным символом. затем, используя dataContext, указывающий на выбранную книгу, свойство text текстового поля привязывается к KeywordsForTextbox.
Я бы предпочел не рассматривать издание текстового поля на данный момент.
Но для комбинированного списка есть две вещи, которые нужно связать:
1 / список всех ключевых слов. Я могу добавить в свой класс BookManagement (который ... управляет классом Book) свойство, получатель которого вернет список всех ключевых слов (по ссылке).
2 / каждый ComboboxItem будет редактироваться в XAML, но как реализовать поведение установки его как отмеченного / непроверенного, если заданное ключевое слово (полученное с помощью свойства ItemSource флажка для свойства Keyword экземпляра Book) содержится в selectedItem Ключевые слова?
короче: как связать свойство selected объекта CheckBoxItem с наличием этой строки в selectedItem.Keywords (список строк) списка ListView?
Я прошу прощения за грязный аспект моего вопроса!
спасибо.
EDIT
Ну, мне удалось написать все, он собирает и запускает, но есть проблема; фактически в выпадающем списке, itemsSource был записан так:
ItemsSource="{Binding Source={StaticResource AllBooks}}"
и AllBooks - это ресурс:
<ObjectDataProvider
x:Key="AllBooks"
MethodName="listOfAllKeywords"
ObjectType="{x:Type mangmt:BookManagement}" />
вот метод:
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>();
}
Когда я запускаю свою программу, окно отображается нормально, но если я нажимаю на книгу, чтобы отобразить ее, и если я нажимаю на поле со списком, при втором щелчке я получаю исключение:
System.InvalidCastException: «Невозможно повлиять на объект типа« MS.Internal.NamedObject ». Тип« System.String ».
что поговорка невозможна.
В отладке я увидел, что в мультибиндинге параметр secondf имеет значение null (в любом случае он кажется не очень актуальным, поскольку исключение вызвано первым параметром, но все же это раздражает).
Я вспоминаю вам мой мультисвязь:
<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>
вот ключевые слова для текстового поля:
public string KeywordsForTextbox
{
get { return string.Join(",", _keywords); }
}
(это в классе Книги)
первое связывание (мультисвязывания) неверно? почему?
спасибо.
РЕДАКТИРОВАТЬ 2
Я создал новое сообщение, потому что оно слишком грязное (слишком много текста в моем вопросе), а область возможных причин сильно ограничена, так как я обнаружил, что это проблема dependencyProperty. вот ссылка: здесь в переполнении стека