Najera
Najera

Reputation: 2879

WPF binding to a Usercontrol and getting an error

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

Answers (2)

blindmeis
blindmeis

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

Rohit Vats
Rohit Vats

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

Related Questions