Reputation: 187
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
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
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