views:

44

answers:

0

I have a markup extension that is working with Binding. Things work well except when the markup extension is used in a DataTemplate which is then used by a ContentControl that is bound to the same property as a ListView with IsSynchronizedWithCurrentItem=true. How can I get the CurrentItem from my templated controls instead of each controls' datacontext (which is the collection, not the item)

e.g.

   <ListView ItemsSource="{Binding Things}" IsSynchronizedWithCurrentItem="True" />

and

   <ContentControl 
        ContentTemplate="{StaticResource thingsTemplate}" 
                    Content="{Binding Things}" />

and a "thingsTemplate" with anything you would expect.

My MarkupExtension's ProvideValue looks like this:

 public override object ProvideValue(IServiceProvider serviceProvider)
    {
        //delegate binding creation etc. to the base class
        object val = base.ProvideValue(serviceProvider);

        //try to get bound items for our custom work
        DependencyObject targetObject;
        DependencyProperty targetProperty;
        bool status = TryGetTargetItems(serviceProvider, out targetObject, out targetProperty);

        if (status && targetObject is FrameworkElement)
        {
            FrameworkElement element = targetObject as FrameworkElement;
            BindingExpression elementGetBindingExpression = val as BindingExpression;
            INotifyPropertyChanged dataContext = element.DataContext as INotifyPropertyChanged;
            element.DataContextChanged += (changedElement, dcc) =>
            {
                FrameworkElement fe = changedElement as FrameworkElement;
                var ebe = fe.GetBindingExpression(targetProperty);
                var dc = fe.DataContext as INotifyPropertyChanged;
                if (null != ebe && null != dc)
                    wirePropertyChanged(ebe, dc);
            };
            // This is where things go terribly bad and I cannot figure out how to handle things.
            // it works fine for a datatemplate that is bound directly, but not with IsSynchronized...
            FrameworkElement templatedParentElement = element.TemplatedParent as FrameworkElement;
            if (templatedParentElement is ContentPresenter && (templatedParentElement as ContentPresenter).Content is INotifyPropertyChanged)
                dataContext =
                    (templatedParentElement as ContentPresenter).Content as INotifyPropertyChanged;
            else
                dataContext = templatedParentElement.DataContext as INotifyPropertyChanged;
            if (null != templatedParentElement)
                wirePropertyChanged(elementGetBindingExpression, dataContext);

            if (null != elementGetBindingExpression && null != dataContext)
                wirePropertyChanged(elementGetBindingExpression, dataContext);
            return val;
        }
        else return this;
    }

Any pointers to how WPF and ContentControl do their magic of IsSynchronizedWithCurrentItem would help. I know I could change the "Things" property to which things are bound to an ICollectionView (it is an ObservableCollection) and read CurrentItem off of that, but I am hoping for a more general solution that will work in all cases of the ContentControl and DataTemplate.