Xanagandr
Xanagandr

Reputation: 763

WPF: Binding Property from User Control to ViewModel

I have a UserControl named AntecedentControl:

The XAML:

<UserControl x:Name="AntecedentUserControl">

<ScrollViewer DataContext="{Binding ElementName=AntecedentUserControl}">
    <telerik:RadGridView ItemsSource="{Binding Path=AntecedentList}"
                         AutoGenerateColumns="False"

        <telerik:RadGridView.Columns>
            <telerik:GridViewDataColumn DataMemberBinding="{Binding Section, Mode=TwoWay}"
                                        Header="Seccion"
                                        IsVisible="True"
                                        IsFilterable="False"/>
            <telerik:GridViewDataColumn DataMemberBinding="{Binding Group, Mode=TwoWay}"
                                    Header="Grupo"
                                    IsVisible="True"
                                    IsFilterable="False"/>
            <telerik:GridViewDataColumn DataMemberBinding="{Binding Tome, Mode=TwoWay}"
                                    Header="Tomo"
                                    IsVisible="True"
                                    IsFilterable="False"/>
            <telerik:GridViewDataColumn DataMemberBinding="{Binding Volume, Mode=TwoWay}"
                                    Header="Volumen"
                                    IsVisible="True"
                                    IsFilterable="False"/>
            <telerik:GridViewDataColumn DataMemberBinding="{Binding Inscription, Mode=TwoWay}"
                                    Header="Inscripcion"
                                    IsVisible="True"
                                    IsFilterable="False"/>
            <telerik:GridViewDataColumn DataMemberBinding="{Binding Bis, Mode=TwoWay}"
                                    Header="Bis"
                                    IsVisible="True"
                                    IsFilterable="False"/>
            <telerik:GridViewColumn>
                <telerik:GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <telerik:RadButton Content="Delete"
                                           Command="telerikGrid:RadGridViewCommands.Delete"
                                           CommandParameter="{Binding}"/>
                    </DataTemplate>
                </telerik:GridViewColumn.CellTemplate>
            </telerik:GridViewColumn>
        </telerik:RadGridView.Columns>

    </telerik:RadGridView>
</ScrollViewer>

The code-behind (C#):

public partial class AntecedentControl : UserControl
{
    public ObservableCollection<Antecedent> AntecedentList
    {
        get { return (ObservableCollection<Antecedent>)GetValue(AntecedentListProperty); }
        set { SetValue(AntecedentListProperty, value); }
    }

    public static readonly DependencyProperty AntecedentListProperty =
        DependencyProperty.Register("AntecedentList",
        typeof(ObservableCollection<Antecedent>),
        typeof(AntecedentControl),
        new FrameworkPropertyMetadata(new ObservableCollection<Antecedent>(), OnListPropertyChanged));

    private static void OnListPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
    {
        var antecedentList = source as AntecedentControl;
        var value = e.NewValue as ObservableCollection<Antecedent>;
        antecedentList.AntecedentList = value;
    }

    public AntecedentControl()
    {
        InitializeComponent();
    }
}

And, on a separate view, I am calling this UserControl, like this:

<DomainTransmissionControls:AntecedentControl AntecedentList="{Binding ElementName=AntecedentUserControl, Path=Antecedents, Mode=TwoWay}"/>

On the ViewModel of this separate view, I have a Property called 'Antecedents':

public ObservableCollection<Antecedent> Antecedents { get; set; }

In simple words: The AntecedentControl UC is a grid that has a method where you can add/edit items on said grid. The property 'AntecedentList' of the current UC is where the list is being 'saved'.

The property 'Antecedents' of the ViewModel of the other UC where the 'AntecedentControl' is being called should be bound to 'AntecedentList' of AntecedentControl UC.

I would like to know how I can bind this property on the ViewModel to the property 'AntecedentList' property found in the separate UserControl (AntecedentControl), since this current code returns null.

I believe there is something wrong with my DependencyProperty declaration on the AntecedentControl UC, since putting a breakpoint on the 'OnListPropertyChanged' method reveals e.NewValue is returning null.

If so, why is not returning the default value declared in the Dependency Property statement?

Thank you for your time.

Upvotes: 0

Views: 2160

Answers (1)

Derrick Moeller
Derrick Moeller

Reputation: 4960

Your binding appears to be incorrect. You appear to be attempting to access an element(AntecedentUserControl) that is inside the UserControl you've created?

Unless you've left out some code for simplicities sake, it actually seems like you don't even need a DependencyProperty? Is there any reason you can't set the DataContext?

SomeView.xaml

<DomainTransmissionControls:AntecedentControl DataContext="{Binding Antecedents}" />

SomeViewModel.cs

private ObservableCollection<Antecedent> _antecedents;

public ObservableCollection<Antecedent> Antecedents
{
    get
    {
        if (_antecedents == null)
            _antecedents = new ObservableCollection<Antecedent>();

        return _antecedents;
    }
}

AntecedentControl.xaml

<UserControl>
    <ScrollViewer>
       <telerik:RadGridView ItemsSource="{Binding}" AutoGenerateColumns="False">
            <telerik:RadGridView.Columns>
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Section, Mode=TwoWay}"
                                            Header="Seccion" IsFilterable="False" IsVisible="True" />
                <!-- Additional column definitions. -->
            </telerik:RadGridView.Columns>
        </telerik:RadGridView>
    </ScrollViewer>
</UserControl>

AntecedentControl.xaml.cs

public partial class AntecedentControl : UserControl
{
    public AntecedentControl()
    {
        InitializeComponent();
    }
}

Upvotes: 1

Related Questions