views:

25

answers:

0

I've been doing some work in WPF, and I for the most part have my bindings working, but I need a scope clarification here. I've run into some seemingly simple operations that require silly binding workarounds and I believe a lot of it has to do with scope.

Example #1 - Out of visual tree, binding to parent.

<ComboBox x:Name="Combo1" ItemsSource="{Binding SomeListOfStrings}">
  <ComboBox.ContextMenu>
    <ContextMenu>
      <MenuItem Header="{Binding ElementName=Combo1, Path=SelectedItem}" />
      <MenuItem Header="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}, Path=SelectedItem}" />
    </ContextMenu>
  </ComboBox.ContextMenu>
</ComboBox>

In this example, I'm trying to bind a child-element's property to a parent's property. Since this item isn't in the visual tree under the element, but instead as just a property, I cannot locate the parent using FindAncestor. In my experience I've had no luck binding with ElementName in this case either (Tried both Name="" and x:Name="").

What is the scope here? How does the MenuItem relate to the ComboBox? Because I know it inherits the DataContext of it's parent here, why is it unreachable with FindAncestor / ElementName?

Example #2 - Resources + StaticResource/DynamicResource

<UserControl x:Name="MainControl" ... />
  <UserControl.Resources>
     <Style TargetType="ComboBox">
       <Setter Property="ContextMenu">
         <Setter.Value>
           <ContextMenu ItemsSource="{Binding ViewModelsMenuItems}" />
         </Setter.Value>
       </Setter>
     </Style>
     <Style TargetType="ComboBox" x:Key="Example2_Style2">
       <Setter Property="ContextMenu">
         <Setter.Value>
           <ContextMenu ItemsSource="{Binding ElementName=MainControl, Path=DataContext.ViewModelMenuItems}" />
         </Setter.Value>
       </Setter>
     </Style>
  </UserControl.Resources>
  <StackPanel>
    <ComboBox />
    <ComboBox />
    <ComboBox Style="{StaticResource Example2_Style2" />
  </StackPanel>
</UserControl>

In this example, I'm trying to set the context menu for all ComboBox's in my user control (or specific ones if I used a named style). Since the ContextMenu is defined outside of scope, and "set" into scope, I've experienced issues before with the DataContext being inherited, Or being able to use ElementName (Because the item is out of scope?).

Bonus Question

Since I've had terrible luck alltogether with ElementName can someone please tell me which to use, because I see both ALL OVER the internet/books. Name="Whatever" or x:Name="Whatever"

Update (As per request)

The type of binding failures I am getting are:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ComboBox', AncestorLevel='1''. BindingExpression:Path=SelectedItem; DataItem=null; target element is 'MenuItem' (Name=''); target property is 'Header' (type 'object')