Quantcast
Channel: Windows Presentation Foundation (WPF) forum
Viewing all articles
Browse latest Browse all 18858

Binding an Obserable Collection exposed as a Dependency Property

$
0
0

Given this XAML in a Generic User Control I am creating for re-usability. All I have in it is a ListBox.  Let's just call this the GenericUserControl.

<ListBox x:Name="XDG"
		Height="Auto"            
		ItemsSource="{Binding}"><ListBox.ItemTemplate><DataTemplate><Button></Button></DataTemplate></ListBox.ItemTemplate></ListBox>

From there I expose an ObservableCollection<Button> as a DP with CLR Wrapper

  public partial class GenericNavigator : UserControl
    {
        public static GenericNavigator _this;
        public GenericNavigator()
        {
            _this = this;           
            InitializeComponent();
            TheButtonCollection = new ObservableCollection<Button>();
            XDG.ItemsSource = TheButtonCollection;           
        }

        public static readonly DependencyProperty TheButtonCollectionProperty =
            DependencyProperty.Register("TheButtonCollection", typeof(ObservableCollection<Button>), typeof(GenericNavigator),
                new PropertyMetadata(null,
                    new PropertyChangedCallback(OnNewButtonCollection)));

        private static void OnNewButtonCollection(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            _this.XDG.ItemsSource = (ObservableCollection<Button>) e.NewValue;
        }
        [Category("The Properties")]
        public ObservableCollection<Button> TheButtonCollection {
            get { return (ObservableCollection<Button>)GetValue(TheButtonCollectionProperty); }
            set { SetValue(TheButtonCollectionProperty, value); } 
        }

    }

So far so good... I go to add this control to another User Control...and am easily able to add buttons using the properties page as shown here.  Let's just call this UserControl2

<Templates:GenericNavigator>

<Templates:GenericNavigator.TheButtonCollection> <Button Width="10">test</Button><Button>test</Button><Button>test</Button><Button>test</Button><Button>test</Button><Button>test</Button><Button>test</Button><Button>test</Button></Templates:GenericNavigator.TheButtonCollection></Templates:GenericNavigator>

Now the interesting thing is that as each button is added, the designer shows it, but I can't get the text to show up... I did some debugging and found out by hooking a CollectionChanged event handler in the Generic User Control that it appears that the Button is being created but the context is indeed null.  This means that the button being injected is the actual item template button, which has no text. So I added some text to the GenericUserControl's Button template and viola just that text appeared for every button. Not the text seen above.

I then tried this markup in the GenericControl's XAML:

<ListBox x:Name="XDG"
		Height="Auto"            
		ItemsSource="{Binding}"><ListBox.ItemTemplate><DataTemplate><Button Content="{Binding Mode=OneWay, RelativeSource={RelativeSource PreviousData}}"></Button></DataTemplate></ListBox.ItemTemplate></ListBox>

And it works. With one exception.... The designer shows me this constant error:

"Error 1 The property 'Content' cannot be data bound to a visual element."

So either the designer is wrong, because it compiles and runs and shows what I want, or the Designer is right and this shouldn't be done.

Anyway the question is this, how do I inject Buttons from a Parent container of a re-usable GenericControl set up to "house" controls of a certain type. I'm close because the properties page recognizes this and opens up and allows me to select new for each new button. The properties page is what injected the buttons in the example above.  Things are close but no cigar....  


JP Cowboy Coders Unite!


Viewing all articles
Browse latest Browse all 18858

Trending Articles