wsick / Fayde

Inspired by Silverlight; XAML engine using Javascript and rendering to the HTML5 Canvas.
MIT License
189 stars 27 forks source link

Set Binding Source using ElementName doesn't work in Item Template. #128

Closed Sally-Xu closed 9 years ago

Sally-Xu commented 9 years ago

I'm trying to set binding in ContextMenu's ItemTemplate. Here is the testing XAML:

<TextBlock Grid.Row="1" MouseLeftButtonDown="{EventBinding Command={Binding Path=DataContext.MenuClickCmd, ElementName=Root, CommandParameter={Binding}}}" Text="Test" />

<Border Grid.Row="2" Background="Black" Padding="5" HorizontalAlignment="Center" VerticalAlignment="Center" x:Name="Root">
  <TextBlock Foreground="White" Text="Right click me!">
    <controls:ContextMenuService.ContextMenu>
      <controls:ContextMenu ItemsSource="{Binding Menu}">
        <controls:ContextMenu.ItemTemplate>
          <DataTemplate>
            <Grid>     
              <TextBlock MouseLeftButtonDown="{EventBinding Command={Binding Path=DataContext.MenuClickCmd, ElementName=Root, CommandParameter={Binding}}}" Text="{Binding Header}" />
            </Grid>
          </DataTemplate>
        </controls:ContextMenu.ItemTemplate>           
      </controls:ContextMenu>
    </controls:ContextMenuService.ContextMenu>
  </TextBlock>
</Border>

The TextBlock outside of the ContextMenu's ItemTemplate works fine. But the one inside the ItemTemplate can't find the "Root" Element set in the ElementName binding field. I'm getting "[EVENTBINDING]: Could not find command target for event 'MouseLeftButtonDown'." error at EventBindingExpression.ts:80 .

Sally-Xu commented 9 years ago

Instead of using ElementName=XXX, using RelativeSource = {RelativeSource ItemsControlParent} is working.

This one works:

<DataTemplate>
<TextBlock MouseLeftButtonDown="{EventBinding Command={Binding Path=DataContext.MenuClickCmd, RelativeSource={RelativeSource ItemsControlParent}}, CommandParameter={Binding}}}" Text="{Binding Header}" />
</DateTemplate>
BSick7 commented 9 years ago

This doesn't work in Silverlight either.

Sally-Xu commented 9 years ago

If I remember correctly, that was how it works in Silverlight (by using ElementName). I don't think Silverlight/WPF even has ItemsControlParent in RelativeSource. But I like ItemsControlParent, just need to be documented it if that's how it supposed to work.

BSick7 commented 9 years ago

I tried the example in Silverlight and it doesn't work. Binding cannot find the specified ElementName because it belongs to a different logical tree. To be able to do this would require attaching the ContextMenu to the parent logical tree; however, this introduces other problems.

Sally-Xu commented 9 years ago

Just tried to set RelativeSource with AncestorType=ItemsControl

RelativeSource={RelativeSource AncestorType=ItemsControl} => This doesn't work either.

The only way to make it work is to set RelativeSource={RelativeSource ItemsControlParent}

BSick7 commented 9 years ago

Fayde requires Mode=FindAncestor to be explicitly set. Opened new issue #139 to track.