mecocopy
mecocopy

Reputation: 187

BindingExpression path error in wpf mvvm

I have problem in my binding and I don't know why. I am using Devexpress MVVM. I have a user control which I used to populate textbox based on my ObservableCollection which is working well.

I have this xaml code in my user control.

<ItemsControl IsTabStop="False" ItemsSource="{Binding ListControls}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid HorizontalAlignment="Stretch">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="50"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="50"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="50"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="50"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Label Grid.Column="0"  Content="{Binding RGN_INdex}" />
                <TextBox  Text="{Binding RGN}" Grid.Column="1" >
                    <TextBox.InputBindings>
                        <KeyBinding Key="F1" Command="{Binding InsertControlCommand}" CommandParameter="{Binding Path=RGN_INdex }" />
                    </TextBox.InputBindings>
                </TextBox>
                <Label Grid.Column="2"  Content="RSN:" />
                <TextBox  Text="{Binding RSN}" Grid.Column="3" />
                <Label Grid.Column="4"  Content="SGN:" />
                <TextBox  Text="{Binding SGN}" Grid.Column="5" />
                <Label Grid.Column="6"  Content="SN:" />
                <TextBox  Text="{Binding SN}" Grid.Column="7" />
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

The above code is working until I add the InsertControlCommand .

<TextBox.InputBindings>
     <KeyBinding Key="F1" Command="{Binding InsertControlCommand}" CommandParameter="{Binding Path=RGN_INdex }" />
</TextBox.InputBindings>

It gives me:

System.Windows.Data Error: 40 : BindingExpression path error: 'InsertControlCommand' property not found on 'object' ''RelativesM' (HashCode=41849684)'. BindingExpression:Path=InsertControlCommand; DataItem='RelativesM' (HashCode=41849684); target element is 'KeyBinding' (HashCode=2666760); target property is 'Command' (type 'ICommand')

Why does it doesn't find the InsertControlCommand when that command and the ListControls ObservableCollection are in the same Class(ViewModel)?

This is my ViewModelBase where the InsertControlCommand and ListControls are located.

public abstract class ViewModelBase : INotifyPropertyChanged {
    public DelegateCommand<object> InsertControlCommand { get; private set; }
    public ObservableCollection<Model.RelativesM> ListControls { get; set; }
    public ViewModelBase() {
    InsertControlCommand = new DelegateCommand<object>(InsertControlEvent);
    ListControls = new ObservableCollection<Model.RelativesM>();
    }
}

Then I have this MainViewModel:

public class MainViewModel : ViewModelBase {
    }

Then on my MainWindow.xaml I set the DataContext with this code:

<Window.DataContext>
    <vm:MainViewModel/>
</Window.DataContext>

Upon my understanding my code should work. Because the ListControls and InsertControlCommand use the same ViewModel, but the command doesn't. What is the reason? What did I miss?

Upvotes: 0

Views: 1697

Answers (2)

mm8
mm8

Reputation: 169150

Why does it doesn't find the InsertControlCommand when that command and the ListControls ObservableCollection are in the same Class(ViewModel)?

Because you have one TextBox per item in the ObservableCollection<Model.RelativesM> and the DataContext of each TextBox is the current RelativesM model object in the ObservableCollection<Model.RelativesM> and not the view model itself.

To be able to bind to a property of the view model, you could use a {RelativeSource} binding as suggested by @LittleBit:

<TextBox Text="{Binding RGN}" Grid.Column="1" >
    <TextBox.InputBindings>
        <KeyBinding Key="F1" Command="{Binding DataContext.InsertControlCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
                             CommandParameter="{Binding Path=RGN_INdex }" />
    </TextBox.InputBindings>
</TextBox>

Upvotes: 2

LittleBit
LittleBit

Reputation: 1201

If you bind it like this, it wont look for the InsertControlCommand in your DataContext (MainViewModel) but in your RelativesM Class. This is clearly displayed in your Error Message:

'InsertControlCommand' property not found on 'object' ''RelativesM'

Change your Binding of the Command to;

Command="{Binding DataContext.InsertControlCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}}"

And it should work as you expected.

Upvotes: 2

Related Questions