DependencyProperty.unsetValue in a multibinding
up vote
0
down vote
favorite
I have a listView of items which are 'Book' instances, and when I click on a book the combobox should display its keywords; in fact it's a little trickier : the combobox contains the list of all the keywords of all books (duplicates removed)(the comboboxItems are checkboxes), and those of the selected book are checked.
here is the 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,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>
When I run my program, is seems ok when I click on a book, but I get an exception when I click on the combobox : impossible cast from 'MS.Internal.NamedObject' to 'System.String' type. I saw that value[0] is UnsetValue.
At debugging, when I use spies to track the value of WpfApp1.App.Books[0].KeywordsForTextbox, it gives me the good value (a string which is the list of the keywords of Book[0]. maybe the problem comes from listboxBooks.SelectedItem.KeywordsForTextBox? I can't spy in VS the value of 'listboxBooks'.
some related content...
the beginning of the constructor of MainWindow:
public MainWindow()
{
InitializeComponent();
listBoxBooks.ItemsSource = App.Books;
the convert method of the converter:
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;
}
the KeywordsForTextbox method:
public string KeywordsForTextbox
{
get { return string.Join(",", _keywords); }
}
and finally the implementation of AllBooks:(as a window resource)
<ObjectDataProvider
x:Key="AllBooks"
MethodName="listOfAllKeywords"
ObjectType="{x:Type mangmt:BookManagement}" />
thank you.
c# wpf data-binding
|
show 2 more comments
up vote
0
down vote
favorite
I have a listView of items which are 'Book' instances, and when I click on a book the combobox should display its keywords; in fact it's a little trickier : the combobox contains the list of all the keywords of all books (duplicates removed)(the comboboxItems are checkboxes), and those of the selected book are checked.
here is the 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,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>
When I run my program, is seems ok when I click on a book, but I get an exception when I click on the combobox : impossible cast from 'MS.Internal.NamedObject' to 'System.String' type. I saw that value[0] is UnsetValue.
At debugging, when I use spies to track the value of WpfApp1.App.Books[0].KeywordsForTextbox, it gives me the good value (a string which is the list of the keywords of Book[0]. maybe the problem comes from listboxBooks.SelectedItem.KeywordsForTextBox? I can't spy in VS the value of 'listboxBooks'.
some related content...
the beginning of the constructor of MainWindow:
public MainWindow()
{
InitializeComponent();
listBoxBooks.ItemsSource = App.Books;
the convert method of the converter:
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;
}
the KeywordsForTextbox method:
public string KeywordsForTextbox
{
get { return string.Join(",", _keywords); }
}
and finally the implementation of AllBooks:(as a window resource)
<ObjectDataProvider
x:Key="AllBooks"
MethodName="listOfAllKeywords"
ObjectType="{x:Type mangmt:BookManagement}" />
thank you.
c# wpf data-binding
1
First, i assume that that the Convert method of your TextInListTrueFalseConverter throws the exception. So, is the exception happening when castingvalues[0]
to a string, or when castingvalues[1]
? I would guess it is the latter (the value coming from<Binding RelativeSource="{RelativeSource Self}" Path="Content">
). My recollection about how item objects are associated with item visuals is a bit rusty, but what happens if you use a slightly different binding (referring to the DataContext of the item visual itself):<Binding RelativeSource="{RelativeSource Self}" Path="DataContext">
?
– elgonzo
Nov 10 at 15:48
no, value[0] is the one that throws the exception, the value being DependencyProperty.Unset, a placeholder indicating that there was a problem with the binding. but why, that's my question.
– lolveley
Nov 10 at 16:42
1
Ah, my apologies. I missed the sentence where you mentioned value[0]... Note that your item source for the ComboBox isAllBooks
. Now, don't know precisely what AllBooks is aside it being of typeBookManagement
(some collection with some entries of some type, i suppose). But, obviously, the combobox items would be elements from this BookManagement collection. And thus the KeywordsForTextbox binding would attempt to find the KeywordsForTextbox in the elements of the BookManagement collection. (1/2)
– elgonzo
Nov 10 at 17:01
1
I noticed you talk about KeywordsForTextbox only in conjunction withApp.Books
, but never in conjunction withAllBooks
. If the KeywordsForTextbox property is only provided by the object in listBoxBooks.SelectedItem, you cannot just set the DataContext of the combobox and then be done with it (as the binding in the item template will by default bind against the DataContext of the respective item visual, which is an item object from Combobox.ItemsSource). If you need the items template bind against data "outside" of the resepective item object, you need to specify the binding source(2/2)
– elgonzo
Nov 10 at 17:05
1
<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>
– Simon Evans
Nov 10 at 21:33
|
show 2 more comments
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I have a listView of items which are 'Book' instances, and when I click on a book the combobox should display its keywords; in fact it's a little trickier : the combobox contains the list of all the keywords of all books (duplicates removed)(the comboboxItems are checkboxes), and those of the selected book are checked.
here is the 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,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>
When I run my program, is seems ok when I click on a book, but I get an exception when I click on the combobox : impossible cast from 'MS.Internal.NamedObject' to 'System.String' type. I saw that value[0] is UnsetValue.
At debugging, when I use spies to track the value of WpfApp1.App.Books[0].KeywordsForTextbox, it gives me the good value (a string which is the list of the keywords of Book[0]. maybe the problem comes from listboxBooks.SelectedItem.KeywordsForTextBox? I can't spy in VS the value of 'listboxBooks'.
some related content...
the beginning of the constructor of MainWindow:
public MainWindow()
{
InitializeComponent();
listBoxBooks.ItemsSource = App.Books;
the convert method of the converter:
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;
}
the KeywordsForTextbox method:
public string KeywordsForTextbox
{
get { return string.Join(",", _keywords); }
}
and finally the implementation of AllBooks:(as a window resource)
<ObjectDataProvider
x:Key="AllBooks"
MethodName="listOfAllKeywords"
ObjectType="{x:Type mangmt:BookManagement}" />
thank you.
c# wpf data-binding
I have a listView of items which are 'Book' instances, and when I click on a book the combobox should display its keywords; in fact it's a little trickier : the combobox contains the list of all the keywords of all books (duplicates removed)(the comboboxItems are checkboxes), and those of the selected book are checked.
here is the 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,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>
When I run my program, is seems ok when I click on a book, but I get an exception when I click on the combobox : impossible cast from 'MS.Internal.NamedObject' to 'System.String' type. I saw that value[0] is UnsetValue.
At debugging, when I use spies to track the value of WpfApp1.App.Books[0].KeywordsForTextbox, it gives me the good value (a string which is the list of the keywords of Book[0]. maybe the problem comes from listboxBooks.SelectedItem.KeywordsForTextBox? I can't spy in VS the value of 'listboxBooks'.
some related content...
the beginning of the constructor of MainWindow:
public MainWindow()
{
InitializeComponent();
listBoxBooks.ItemsSource = App.Books;
the convert method of the converter:
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;
}
the KeywordsForTextbox method:
public string KeywordsForTextbox
{
get { return string.Join(",", _keywords); }
}
and finally the implementation of AllBooks:(as a window resource)
<ObjectDataProvider
x:Key="AllBooks"
MethodName="listOfAllKeywords"
ObjectType="{x:Type mangmt:BookManagement}" />
thank you.
c# wpf data-binding
c# wpf data-binding
asked Nov 10 at 13:51
lolveley
7041922
7041922
1
First, i assume that that the Convert method of your TextInListTrueFalseConverter throws the exception. So, is the exception happening when castingvalues[0]
to a string, or when castingvalues[1]
? I would guess it is the latter (the value coming from<Binding RelativeSource="{RelativeSource Self}" Path="Content">
). My recollection about how item objects are associated with item visuals is a bit rusty, but what happens if you use a slightly different binding (referring to the DataContext of the item visual itself):<Binding RelativeSource="{RelativeSource Self}" Path="DataContext">
?
– elgonzo
Nov 10 at 15:48
no, value[0] is the one that throws the exception, the value being DependencyProperty.Unset, a placeholder indicating that there was a problem with the binding. but why, that's my question.
– lolveley
Nov 10 at 16:42
1
Ah, my apologies. I missed the sentence where you mentioned value[0]... Note that your item source for the ComboBox isAllBooks
. Now, don't know precisely what AllBooks is aside it being of typeBookManagement
(some collection with some entries of some type, i suppose). But, obviously, the combobox items would be elements from this BookManagement collection. And thus the KeywordsForTextbox binding would attempt to find the KeywordsForTextbox in the elements of the BookManagement collection. (1/2)
– elgonzo
Nov 10 at 17:01
1
I noticed you talk about KeywordsForTextbox only in conjunction withApp.Books
, but never in conjunction withAllBooks
. If the KeywordsForTextbox property is only provided by the object in listBoxBooks.SelectedItem, you cannot just set the DataContext of the combobox and then be done with it (as the binding in the item template will by default bind against the DataContext of the respective item visual, which is an item object from Combobox.ItemsSource). If you need the items template bind against data "outside" of the resepective item object, you need to specify the binding source(2/2)
– elgonzo
Nov 10 at 17:05
1
<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>
– Simon Evans
Nov 10 at 21:33
|
show 2 more comments
1
First, i assume that that the Convert method of your TextInListTrueFalseConverter throws the exception. So, is the exception happening when castingvalues[0]
to a string, or when castingvalues[1]
? I would guess it is the latter (the value coming from<Binding RelativeSource="{RelativeSource Self}" Path="Content">
). My recollection about how item objects are associated with item visuals is a bit rusty, but what happens if you use a slightly different binding (referring to the DataContext of the item visual itself):<Binding RelativeSource="{RelativeSource Self}" Path="DataContext">
?
– elgonzo
Nov 10 at 15:48
no, value[0] is the one that throws the exception, the value being DependencyProperty.Unset, a placeholder indicating that there was a problem with the binding. but why, that's my question.
– lolveley
Nov 10 at 16:42
1
Ah, my apologies. I missed the sentence where you mentioned value[0]... Note that your item source for the ComboBox isAllBooks
. Now, don't know precisely what AllBooks is aside it being of typeBookManagement
(some collection with some entries of some type, i suppose). But, obviously, the combobox items would be elements from this BookManagement collection. And thus the KeywordsForTextbox binding would attempt to find the KeywordsForTextbox in the elements of the BookManagement collection. (1/2)
– elgonzo
Nov 10 at 17:01
1
I noticed you talk about KeywordsForTextbox only in conjunction withApp.Books
, but never in conjunction withAllBooks
. If the KeywordsForTextbox property is only provided by the object in listBoxBooks.SelectedItem, you cannot just set the DataContext of the combobox and then be done with it (as the binding in the item template will by default bind against the DataContext of the respective item visual, which is an item object from Combobox.ItemsSource). If you need the items template bind against data "outside" of the resepective item object, you need to specify the binding source(2/2)
– elgonzo
Nov 10 at 17:05
1
<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>
– Simon Evans
Nov 10 at 21:33
1
1
First, i assume that that the Convert method of your TextInListTrueFalseConverter throws the exception. So, is the exception happening when casting
values[0]
to a string, or when casting values[1]
? I would guess it is the latter (the value coming from <Binding RelativeSource="{RelativeSource Self}" Path="Content">
). My recollection about how item objects are associated with item visuals is a bit rusty, but what happens if you use a slightly different binding (referring to the DataContext of the item visual itself): <Binding RelativeSource="{RelativeSource Self}" Path="DataContext">
?– elgonzo
Nov 10 at 15:48
First, i assume that that the Convert method of your TextInListTrueFalseConverter throws the exception. So, is the exception happening when casting
values[0]
to a string, or when casting values[1]
? I would guess it is the latter (the value coming from <Binding RelativeSource="{RelativeSource Self}" Path="Content">
). My recollection about how item objects are associated with item visuals is a bit rusty, but what happens if you use a slightly different binding (referring to the DataContext of the item visual itself): <Binding RelativeSource="{RelativeSource Self}" Path="DataContext">
?– elgonzo
Nov 10 at 15:48
no, value[0] is the one that throws the exception, the value being DependencyProperty.Unset, a placeholder indicating that there was a problem with the binding. but why, that's my question.
– lolveley
Nov 10 at 16:42
no, value[0] is the one that throws the exception, the value being DependencyProperty.Unset, a placeholder indicating that there was a problem with the binding. but why, that's my question.
– lolveley
Nov 10 at 16:42
1
1
Ah, my apologies. I missed the sentence where you mentioned value[0]... Note that your item source for the ComboBox is
AllBooks
. Now, don't know precisely what AllBooks is aside it being of type BookManagement
(some collection with some entries of some type, i suppose). But, obviously, the combobox items would be elements from this BookManagement collection. And thus the KeywordsForTextbox binding would attempt to find the KeywordsForTextbox in the elements of the BookManagement collection. (1/2)– elgonzo
Nov 10 at 17:01
Ah, my apologies. I missed the sentence where you mentioned value[0]... Note that your item source for the ComboBox is
AllBooks
. Now, don't know precisely what AllBooks is aside it being of type BookManagement
(some collection with some entries of some type, i suppose). But, obviously, the combobox items would be elements from this BookManagement collection. And thus the KeywordsForTextbox binding would attempt to find the KeywordsForTextbox in the elements of the BookManagement collection. (1/2)– elgonzo
Nov 10 at 17:01
1
1
I noticed you talk about KeywordsForTextbox only in conjunction with
App.Books
, but never in conjunction with AllBooks
. If the KeywordsForTextbox property is only provided by the object in listBoxBooks.SelectedItem, you cannot just set the DataContext of the combobox and then be done with it (as the binding in the item template will by default bind against the DataContext of the respective item visual, which is an item object from Combobox.ItemsSource). If you need the items template bind against data "outside" of the resepective item object, you need to specify the binding source(2/2)– elgonzo
Nov 10 at 17:05
I noticed you talk about KeywordsForTextbox only in conjunction with
App.Books
, but never in conjunction with AllBooks
. If the KeywordsForTextbox property is only provided by the object in listBoxBooks.SelectedItem, you cannot just set the DataContext of the combobox and then be done with it (as the binding in the item template will by default bind against the DataContext of the respective item visual, which is an item object from Combobox.ItemsSource). If you need the items template bind against data "outside" of the resepective item object, you need to specify the binding source(2/2)– elgonzo
Nov 10 at 17:05
1
1
<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>
– Simon Evans
Nov 10 at 21:33
<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>
– Simon Evans
Nov 10 at 21:33
|
show 2 more comments
1 Answer
1
active
oldest
votes
up vote
1
down vote
accepted
The first Binding of the Multi should be to be to the SelectedItem in the ListBox of Books. I have added in the <CheckBox.IsChecked>
where appropriate, and Content="{Binding}" to the CheckBox:
<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>
You may also wish to add some validation to the IMultiValueConverter to make sure the passed values are not unset, to avoid an exception: If Not values(0) Is DependencyProperty.UnsetValue And Not values(1) Is DependencyProperty.UnsetValue Then
in VB.
Regarding the behaviour on checking the checkbox, I am guessing this is because of the ConvertBack Method of the IMultiValueConverter. You can remove the 'Throw Exception' code, and write a method to add/remove the text of the checked/unchecked box to your keyword list.
I tried an other option, maybe worse : stackoverflow.com/questions/53265084/… . do you think it is possible to modify the listview's selectedItem directly from the convertBack method?
– lolveley
2 days ago
Sorry for delay - and saw you have an answer that seems to be working for you, but yes, I think you could use the ConvertBack function to add the CheckBox Content to your List of words. I'd just check the list to see if the word is already included. If it is replace with an empty string, if it is not then add it. So long as the List Property implements INotifyPropertyChanged then your text box should be updated too. You may even consider making your list of keywords an observable collection rather than a string - most of what you're doing is list operations, just convert to string for TextBox
– Simon Evans
yesterday
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
The first Binding of the Multi should be to be to the SelectedItem in the ListBox of Books. I have added in the <CheckBox.IsChecked>
where appropriate, and Content="{Binding}" to the CheckBox:
<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>
You may also wish to add some validation to the IMultiValueConverter to make sure the passed values are not unset, to avoid an exception: If Not values(0) Is DependencyProperty.UnsetValue And Not values(1) Is DependencyProperty.UnsetValue Then
in VB.
Regarding the behaviour on checking the checkbox, I am guessing this is because of the ConvertBack Method of the IMultiValueConverter. You can remove the 'Throw Exception' code, and write a method to add/remove the text of the checked/unchecked box to your keyword list.
I tried an other option, maybe worse : stackoverflow.com/questions/53265084/… . do you think it is possible to modify the listview's selectedItem directly from the convertBack method?
– lolveley
2 days ago
Sorry for delay - and saw you have an answer that seems to be working for you, but yes, I think you could use the ConvertBack function to add the CheckBox Content to your List of words. I'd just check the list to see if the word is already included. If it is replace with an empty string, if it is not then add it. So long as the List Property implements INotifyPropertyChanged then your text box should be updated too. You may even consider making your list of keywords an observable collection rather than a string - most of what you're doing is list operations, just convert to string for TextBox
– Simon Evans
yesterday
add a comment |
up vote
1
down vote
accepted
The first Binding of the Multi should be to be to the SelectedItem in the ListBox of Books. I have added in the <CheckBox.IsChecked>
where appropriate, and Content="{Binding}" to the CheckBox:
<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>
You may also wish to add some validation to the IMultiValueConverter to make sure the passed values are not unset, to avoid an exception: If Not values(0) Is DependencyProperty.UnsetValue And Not values(1) Is DependencyProperty.UnsetValue Then
in VB.
Regarding the behaviour on checking the checkbox, I am guessing this is because of the ConvertBack Method of the IMultiValueConverter. You can remove the 'Throw Exception' code, and write a method to add/remove the text of the checked/unchecked box to your keyword list.
I tried an other option, maybe worse : stackoverflow.com/questions/53265084/… . do you think it is possible to modify the listview's selectedItem directly from the convertBack method?
– lolveley
2 days ago
Sorry for delay - and saw you have an answer that seems to be working for you, but yes, I think you could use the ConvertBack function to add the CheckBox Content to your List of words. I'd just check the list to see if the word is already included. If it is replace with an empty string, if it is not then add it. So long as the List Property implements INotifyPropertyChanged then your text box should be updated too. You may even consider making your list of keywords an observable collection rather than a string - most of what you're doing is list operations, just convert to string for TextBox
– Simon Evans
yesterday
add a comment |
up vote
1
down vote
accepted
up vote
1
down vote
accepted
The first Binding of the Multi should be to be to the SelectedItem in the ListBox of Books. I have added in the <CheckBox.IsChecked>
where appropriate, and Content="{Binding}" to the CheckBox:
<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>
You may also wish to add some validation to the IMultiValueConverter to make sure the passed values are not unset, to avoid an exception: If Not values(0) Is DependencyProperty.UnsetValue And Not values(1) Is DependencyProperty.UnsetValue Then
in VB.
Regarding the behaviour on checking the checkbox, I am guessing this is because of the ConvertBack Method of the IMultiValueConverter. You can remove the 'Throw Exception' code, and write a method to add/remove the text of the checked/unchecked box to your keyword list.
The first Binding of the Multi should be to be to the SelectedItem in the ListBox of Books. I have added in the <CheckBox.IsChecked>
where appropriate, and Content="{Binding}" to the CheckBox:
<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>
You may also wish to add some validation to the IMultiValueConverter to make sure the passed values are not unset, to avoid an exception: If Not values(0) Is DependencyProperty.UnsetValue And Not values(1) Is DependencyProperty.UnsetValue Then
in VB.
Regarding the behaviour on checking the checkbox, I am guessing this is because of the ConvertBack Method of the IMultiValueConverter. You can remove the 'Throw Exception' code, and write a method to add/remove the text of the checked/unchecked box to your keyword list.
answered 2 days ago
Simon Evans
11617
11617
I tried an other option, maybe worse : stackoverflow.com/questions/53265084/… . do you think it is possible to modify the listview's selectedItem directly from the convertBack method?
– lolveley
2 days ago
Sorry for delay - and saw you have an answer that seems to be working for you, but yes, I think you could use the ConvertBack function to add the CheckBox Content to your List of words. I'd just check the list to see if the word is already included. If it is replace with an empty string, if it is not then add it. So long as the List Property implements INotifyPropertyChanged then your text box should be updated too. You may even consider making your list of keywords an observable collection rather than a string - most of what you're doing is list operations, just convert to string for TextBox
– Simon Evans
yesterday
add a comment |
I tried an other option, maybe worse : stackoverflow.com/questions/53265084/… . do you think it is possible to modify the listview's selectedItem directly from the convertBack method?
– lolveley
2 days ago
Sorry for delay - and saw you have an answer that seems to be working for you, but yes, I think you could use the ConvertBack function to add the CheckBox Content to your List of words. I'd just check the list to see if the word is already included. If it is replace with an empty string, if it is not then add it. So long as the List Property implements INotifyPropertyChanged then your text box should be updated too. You may even consider making your list of keywords an observable collection rather than a string - most of what you're doing is list operations, just convert to string for TextBox
– Simon Evans
yesterday
I tried an other option, maybe worse : stackoverflow.com/questions/53265084/… . do you think it is possible to modify the listview's selectedItem directly from the convertBack method?
– lolveley
2 days ago
I tried an other option, maybe worse : stackoverflow.com/questions/53265084/… . do you think it is possible to modify the listview's selectedItem directly from the convertBack method?
– lolveley
2 days ago
Sorry for delay - and saw you have an answer that seems to be working for you, but yes, I think you could use the ConvertBack function to add the CheckBox Content to your List of words. I'd just check the list to see if the word is already included. If it is replace with an empty string, if it is not then add it. So long as the List Property implements INotifyPropertyChanged then your text box should be updated too. You may even consider making your list of keywords an observable collection rather than a string - most of what you're doing is list operations, just convert to string for TextBox
– Simon Evans
yesterday
Sorry for delay - and saw you have an answer that seems to be working for you, but yes, I think you could use the ConvertBack function to add the CheckBox Content to your List of words. I'd just check the list to see if the word is already included. If it is replace with an empty string, if it is not then add it. So long as the List Property implements INotifyPropertyChanged then your text box should be updated too. You may even consider making your list of keywords an observable collection rather than a string - most of what you're doing is list operations, just convert to string for TextBox
– Simon Evans
yesterday
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53239642%2fdependencyproperty-unsetvalue-in-a-multibinding%23new-answer', 'question_page');
}
);
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
1
First, i assume that that the Convert method of your TextInListTrueFalseConverter throws the exception. So, is the exception happening when casting
values[0]
to a string, or when castingvalues[1]
? I would guess it is the latter (the value coming from<Binding RelativeSource="{RelativeSource Self}" Path="Content">
). My recollection about how item objects are associated with item visuals is a bit rusty, but what happens if you use a slightly different binding (referring to the DataContext of the item visual itself):<Binding RelativeSource="{RelativeSource Self}" Path="DataContext">
?– elgonzo
Nov 10 at 15:48
no, value[0] is the one that throws the exception, the value being DependencyProperty.Unset, a placeholder indicating that there was a problem with the binding. but why, that's my question.
– lolveley
Nov 10 at 16:42
1
Ah, my apologies. I missed the sentence where you mentioned value[0]... Note that your item source for the ComboBox is
AllBooks
. Now, don't know precisely what AllBooks is aside it being of typeBookManagement
(some collection with some entries of some type, i suppose). But, obviously, the combobox items would be elements from this BookManagement collection. And thus the KeywordsForTextbox binding would attempt to find the KeywordsForTextbox in the elements of the BookManagement collection. (1/2)– elgonzo
Nov 10 at 17:01
1
I noticed you talk about KeywordsForTextbox only in conjunction with
App.Books
, but never in conjunction withAllBooks
. If the KeywordsForTextbox property is only provided by the object in listBoxBooks.SelectedItem, you cannot just set the DataContext of the combobox and then be done with it (as the binding in the item template will by default bind against the DataContext of the respective item visual, which is an item object from Combobox.ItemsSource). If you need the items template bind against data "outside" of the resepective item object, you need to specify the binding source(2/2)– elgonzo
Nov 10 at 17:05
1
<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>
– Simon Evans
Nov 10 at 21:33