0

I have the following XAML:

<ItemsControl ItemsSource="{Binding...}" >
    <ItemsControl.Template>
        <ControlTemplate>
            <ItemsPresenter x:Name="testGrid"/>
        </ControlTemplate>
    </ItemsControl.Template>
    <!--Use the ItemsPanel property to specify a custom UniformGrid that
    holds the laid out items.-->
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <tools:UniformGridRtL Columns="8" x:Name="testGrid2" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <!--Use the ItemTemplate to set a DataTemplate to define
        the visualization of the data objects. This DataTemplate
        specifies that each data object appears RegisterBit appears
        as a CheckBox bound to RegisterBit properties. It also defines
        a custom template for the checkbox.-->
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <CheckBox... />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

<Label>
    <Binding ElementName="testGrid2" Path="property_of_UniformGridRtL"/>
</Label>

Basically, I have a custom Panel (UniformGridRtL) set as an ItemsPanelTemplate, which will template the ItemsPresenter in the ItemsControl. UniformGridRtL has a property, which I would like to bind to, but ElementName doesn't seem to work in the Label Binding. How can I bind to a property of a generated ItemsControl items host?

Mart
  • 135
  • 1
  • 10

1 Answers1

0

The ElementName binding source doesn't work for templated items, even ItemsPanelTemplate ones which usually only have a single templated item. The problem is that because it's a template you could in theory have more than one, so WPF doesn't know which named item to bind to.

As a work-around, try subscribing to the Loaded event of the panel (in this case <tools:UniformGridRtL Loaded="grid_Loaded" .../>), and then set the binding manually in code:

private void grid_Loaded( object sender, RoutedEventArgs e )
{
    Binding binding = new Binding( "NameOfGridPropertyToBindTo" );
    binding.Source = sender;
    boundLabel.SetBinding( Label.ContentProperty, binding );
}

The code above assumes something like <Label Name="boundLabel"/> for your Label declaration.

Dana Cartwright
  • 1,566
  • 17
  • 26
  • Thanks for the work-around... It indeed works, if the binding target is not a template-item too. What happens, if I want to bind to a sibling element in the same ItemsControl ControlTemplate? – Mart Jan 07 '11 at 17:31
  • If you have a sibling source element, instead of using the sender use (namedItemsControl).Template.FindName() as discussed here: http://stackoverflow.com/questions/820201/how-to-access-a-wpf-control-located-in-a-controltemplate – Dana Cartwright Jan 07 '11 at 19:35
  • Sorry, my comment got cut off - if the target is templated you can use the same strategy with Template.FindName() as well - the code just gets a bit messier. Make sure to still use a Loaded event of some kind though or else you won't have a visual tree yet and FindName will return null. – Dana Cartwright Jan 07 '11 at 19:37