Search code examples
c#wpfxamldata-binding

Recursive UserControl Children Binding


I am trying to build a UserControl which works recursive. So that my UserControl contains itsself and so on.

Xaml

    <Grid>
        <DataGrid x:Name="DGrid" ItemsSource="{Binding CustomItemsSource, ElementName=SourceElement}" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="{Binding Children, ElementName=SourceElement}">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <local:CustomInterfaceGrid  Margin="0,10,0,0"  CustomItemsSource="{Binding Children, ElementName=SourceElement}"></local:CustomInterfaceGrid>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>

        </DataGrid>
    </Grid>
</UserControl>

CodeBehind

public partial class CustomInterfaceGrid : UserControl, INotifyPropertyChanged
  {

    IEnumerable<Object> m_Children;

    #region Init

    public CustomInterfaceGrid()
    {

      InitializeComponent();

    }

    #endregion Init

    #region Properties



    public static readonly DependencyProperty CustomItemsSourceProperty =

    DependencyProperty.Register("CustomItemsSource", typeof(IEnumerable<Object>), typeof(CustomInterfaceGrid),new PropertyMetadata(ItemsSourceChanged));

    private static void ItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
      CustomInterfaceGrid cig = (CustomInterfaceGrid)d;
      if (CustomItemsSourceProperty != null)
      {
        cig.m_Children = cig.getChildren();
      }
    }


    public IEnumerable<Object> Children
    {
      get
      {
        return m_Children;
      }
      set
      {
        if (m_Children != value)
        {
          m_Children = value;
          OnPropertyChanged();
        }
      }
    }
    public IEnumerable<Object> CustomItemsSource
    {
      get
      {
        return GetValue(CustomItemsSourceProperty) as IEnumerable<Object>;
      }
      set {
        SetValue(CustomItemsSourceProperty, value);
        OnPropertyChanged();
      }
    }



    #endregion Properties

    #region Methods

    private ObservableCollection<Object> getChildren()
    {
      {
        if (CustomItemsSource != null)
        {
          ObservableCollection<Object> list = new ObservableCollection<object>();
          foreach (var item in CustomItemsSource)
          {
            list.Add(item);
          }
          return list;
        }
        else return null;
      }
    }

    #endregion Methods

    }

My problem is that, that "Children" doesn't work (thats my guess though). If i debug that application, i get Elements in Children, so its not empty, but hes not displaying anything, as empty Tables from the first CustomItemSource, which gets an Observable Collection.


Solution

  • There is no element named "SourceElement" in your example.

    If you want to bind to a property of the CustomInterfaceGrid element itself, you could use the RelativeSource property:

    <local:CustomInterfaceGrid
        CustomItemsSource="{Binding Children, RelativeSource={RelativeSource Self}}" />