I have a C# WPF 4.51 application. On one of my XAML forms I have a list box that has its ItemsSource property bound to a property in my main ViewModel that is of type Collection . When the Collection was of type string , everything worked fine and I saw the collection of strings in the list box.
But then I changed the type in the Collection to a class named ObservableStringExt . The class has two fields: StrItem that contains the string I want displayed in the list box, and IsSelected , a supporting field. I then created a value converter to extract the StrItem field and return it.
However, when I look at the targetType passed to the Convert() method of the value converter I see a type of IEnumerable . Given that the Count property in that parameter matches the number of list items expected, it looks like the Convert() method is receiving a reference to the entire Collection instead of ObservableStringExt , the type of each item in the Collection. This of course is a problem. What is causing this? I have done this sort of thing many times in Windows Phone and WinRT (windows store apps) many times without trouble.
Here is the code for the value converter:
public class ObservableStringExtToStrItem : IValueConverter
{
// The targetType of the value received is of type IEnumerable, not ObservableStringExt.
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is ObservableStringExt)
return (value as ObservableStringExt).StrItem;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Below is the XAML code for the list box. Note Commands_FrequentyUsed is a property of type ObservableCollectionWithFile found in the main view model, which is the data context for the entire form:
<ListBox x:Name="listFrequentlyUsedCommands"
Width="278"
Height="236"
Margin="30,103,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
ItemsSource="{Binding Commands_FrequentyUsed.Collection,
Converter={StaticResource ObservableStringExtToStrItem}}" />
Here is the code for the class that contains the Collection that the list box binds to and the class the Collection contains:
public class ObservableStringExt
{
public string StrItem { get; set;}
public bool IsSelected{ get; set; }
}
public class ObservableCollectionWithFile : BaseNotifyPropertyChanged
{
public const string CollectionPropertyName = "Collection";
private ObservableCollection<ObservableStringExt> _observableCollection = new ObservableCollection<ObservableStringExt>();
public ObservableCollection<ObservableStringExt> Collection
{
get { return _observableCollection; }
private set { SetField(ref _observableCollection, value); }
}
} // public class ObservableCollectionWithFile
I just had the same problem. Not sure how it should normally work, but changing the converter to also convert list of items helped (I found this easier than creating a separate converter for List)
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var list = value as IEnumerable<ObservableStringExt>;
if (list != null)
{
return list.Select(x => Convert(x, typeof(string), null, culture));
}
if (value is ObservableStringExt)
return (value as ObservableStringExt).StrItem;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.