views:

1738

answers:

1

I’m creating a UserControl for a rich TreeView (one that has context menus for renaming nodes, adding child nodes, etc.). I want to be able to use this control to manage or navigate any hierarchical data structures I will create. I currently have it working for any data structure that implements the following interface (the interface need not actually be implemented, however, only the presence of these members is required):

interface ITreeItem
{
    string Header { get; set; }
    IEnumerable Children { get; }
}

Then in my UserControl, I use templates to bind my tree to the data structure, like so:

<TextBlock x:Name="HeaderTextBlock" Text="{Binding Path=Header}" />

What I would like to do is define the name of each of these members in my RichTreeView, allowing it to adapt to a range of different data structures, like so:

class MyItem
{
    string Name { get; set; }
    ObservableCollection<MyItem> Items;
}

<uc:RichTreeView ItemSource={Binding Source={StaticResource MyItemsProvider}} 
    HeaderProperty="Name" ChildrenProperty="Items" />

Is there any way to expose the Path of a binding inside a UserControl as a public property of that UserControl? Is there some other way to go about solving this problem?

+1  A: 

Perhaps this might help:

Create a new Binding when you set the HeaderProperty property on the Header dependency property:

Header property is your normal everyday DependencyProperty:

    public string Header
    {
        get { return (string)GetValue(HeaderProperty); }
        set { SetValue(HeaderProperty, value); }
    }

    public static readonly DependencyProperty HeaderProperty =
        DependencyProperty.Register("Header", typeof(string), typeof(ownerclass));

and the property of your HeaderProperty works as follows:

    public static readonly DependencyProperty HeaderPropertyProperty =
        DependencyProperty.Register("HeaderProperty", typeof(string), typeof(ownerclass), new PropertyMetadata(OnHeaderPropertyChanged));

    public string HeaderProperty        
    {
        get { return (string)GetValue(HeaderPropertyProperty); }
        set { SetValue(HeaderPropertyProperty, value); }
    }

   public static void OnHeaderPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        if (args.NewValue != null)
        {
            ownerclass c = (ownerclass) obj;

            Binding b = new Binding();
            b.Path = new PropertyPath(args.NewValue.ToString());
            c.SetBinding(ownerclass.HeaderProperty, b);
        }
    }

HeaderProperty is your normal everyday DependencyProperty, with a method that is invoked as soon as the HeaderProperty changes. So when it changes , it creates a binding on the Header which will bind to the path you set in the HeaderProperty. :)

Hope this helps...

PS You need to set your ownerclass of course for it to compile ;)

Arcturus