问题
I'm trying to bind SelectedItem in a ListView to the property SelectedSection in the viewmodel. I'm getting the following error: "Invalid binding path 'ViewModel.SelectedSection' : Cannot bind type 'Model.Section' to 'System.Object' without a converter". I'm currently binding the ListView's ItemSource to a list in the CurrentProject property. I tried making a converter, but I'm not quite sure how and what I'm suppose to convert. I got the same error when I tried to just get the property I need using SelectedValue and SelectedValuePath.
<ListView Name="SectionsListView"
IsItemClickEnabled="True"
ItemsSource="{x:Bind ViewModel.CurrentProject.Sections, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.SelectedSection, Mode=TwoWay}">
ViewModel:
private Section selectedSection = new Section();
public Section SelectedSection
{
get { return selectedSection; }
set { selectedSection = value; OnPropertyChanged(nameof(SelectedSection)); }
}
private Project currentProject;
public Project CurrentProject
{
get { return currentProject; }
set { currentProject = value; OnPropertyChanged(nameof(CurrentProject)); }
}
Converter:
public object Convert(object value, Type targetType, object parameter, string language)
{
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return value as Section;
}
回答1:
If you had implemented this with the traditional {Bindings } markup you wouldn't have this issue, since the bindings are evaluated at runtime, while {x:Bind } is evaluated at compile time.
The situation here is that both ItemsSource and SelectedItem are properties of type Object and hence the problem arises when your Target tries to update the Source, due to the fact that you cannot assign a property of type Object to your (ViewModel.SelectedSection) property. The opposite doesn't throw any error since you your ViewModel.SelectedSection property can be implicitly casted to object.
One of the features of x:Bind, is that you can can cast your properties, like this for example:
{x:Bind (x:Boolean)CheckBox.IsChecked, Mode=TwoWay}"
The problem is that since in your situation we are not dealing with one of the XAML intrinsic data types, you have to map onto your XAML namespace your ViewModel class, by including it on your XML namespace defined at the root of your page.
xmlns:myviewmodel="using:......"
After including it, i think you can successfully cast it onto the desired reference type, without any compilation error, by performing casting like this:
<ListView Name="SectionsListView"
IsItemClickEnabled="True"
ItemsSource="{x:Bind ViewModel.CurrentProject.Sections, Mode=OneWay}"
SelectedItem="{x:Bind (myviewmodel:ViewModel) ViewModel.SelectedSection, Mode=TwoWay}">
Or you can make some tweaks on your code and work with {Binding }, which honestly just simplifies entirely this process!
回答2:
Thanks for your response, I got it working by setting the datacontext to the viewmodel and used regular binding instead.
<ListView Name="SectionsListView"
DataContext="{x:Bind ViewModel}"
ItemsSource="{Binding CurrentProject.Sections, Mode=OneWay}"
SelectedItem="{Binding SelectedSection, Mode=TwoWay}">
来源:https://stackoverflow.com/questions/47757516/uwp-listview-bind-selecteditem-to-property-in-viewmodel