Reputation: 2879
Im starting with WPF, sorry if i cant explain well, and i have hours trying to solve how to bind a collection to a custom grid is named PagingDataGrid.
The PagingDataGrid is in CustomerSearchControl binding GridItems to ItemsSource, when i excecute SearchCommand GridItems gets updated but nothing else changes.
I get the following error:
System.Windows.Data Error: 40 : BindingExpression path error: 'GridItems' property not found on 'object' ''PagingDataGridViewModel' (HashCode=54151655)'. BindingExpression:Path=GridItems; DataItem='PagingDataGridViewModel' (HashCode=54151655); target element is 'PagingDataGrid' (Name='Me'); target property is 'ItemsSource' (type 'IEnumerable')
CustomerSearchControl:
<UserControl x:Class="Namespace.CustomerSearchControl"
... >
<Control.DataContext>
<Binding Path="CustomerSearchViewModel" ... />
</Control.DataContext>
<DockPanel LastChildFill="True">
<GroupBox Header="Registros">
<controls:PagingDataGrid ItemsSource="{Binding GridItems}" Height="300" />
</GroupBox>
</DockPanel>
</UserControl>
public class CustomerSearchViewModel : ViewModelBase
{
public ObservableCollection<GridItem> GridItems{ get; set; }
public ICommand SearchCommand { get; set; }
public CustomerSearchViewModel()
{
GridItems = new ObservableCollection<GridItem>();
SearchCommand = new RelayCommand(SearchEntities, () => true);
}
}
PagingDataGrid:
<UserControl x:Class="Namespace.PagingDataGrid" x:Name="Me"
... >
<UserControl.DataContext>
<Binding Path="PagingDataGridViewModel" ... />
</UserControl.DataContext>
<Grid>
...
<xcdg:DataGridControl
ItemsSource="{Binding ElementName=Me, Path=ItemsSource}" Grid.Row="0"/>
</Grid>
</UserControl>
public partial class PagingDataGrid : UserControl
{
public static readonly DependencyProperty ItemsSourceProperty
= DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(PagingDataGrid),
new PropertyMetadata(default(IEnumerable)));
public IEnumerable ItemsSource
{
get { return (IEnumerable)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
}
Upvotes: 0
Views: 934
Reputation: 22435
never set the datacontext of your usercontrol to self. so simply remove
<UserControl.DataContext>
<Binding Path="PagingDataGridViewModel" ... />
</UserControl.DataContext>
EDIT: if you not remove this, then your
<UserControl x:Class="Namespace.PagingDataGrid" x:Name="Me">
<UserControl.DataContext>
<Binding Path="PagingDataGridViewModel" ... />
</UserControl.DataContext>
<Grid>
<xcdg:DataGridControl ItemsSource="{Binding ElementName=Me, Path=ItemsSource}" Grid.Row="0"/>
</Grid>
</UserControl>
datacontext for your usercontrol is PagingDataGridViewModel and if PagingDataGridViewModel dont have a property ItemsSource you get an error. you never get the GridItems from your CustomerSearchViewModel that you want.
Upvotes: 1
Reputation: 81243
You need to declare instance of CustomerSearchViewModel
in XAML and bind to DataContext.
This is how to do it:
<UserControl.DataContext>
<local:CustomerSearchViewModel/>
</UserControl.DataContext>
Make sure to declare namespace local
at root i.e. at UserControl:
xmlns:local="clr-namespace:WpfApplication" <-- Replace WpfApplication with
actual namespace of your ViewModel.
Not needed since getting instance from ServiceLocator.
And for binding to GridItems
you need to bind explicitly to CustomerSearchControl
DataContext using RelativeSource
. This is needed because you have explicitly set DataContext on PagingDataGrid
to PagingDataGridViewModel
. So, it will search for GridItems
property in PagingDataGridViewModel instead of CustomerSearchViewModel.
<controls:PagingDataGrid ItemsSource="{Binding DataContext.GridItems,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=UserControl}}"/>
Or you can give x:Name
to CustomerSearchControl
and bind using ElementName
.
Upvotes: 1