0

I have a Button whose XAML is like this

<Button x:Name="Button2" Style="{StaticResource User_Hyperlink_Button}" Tag="123456789.XAML" Width="86" Height="30" Margin="26,327,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Content="Button2" />

The style for the the Button is defined in the ResourceDictionary like this

<Style x:Key="User_Hyperlink_Button" TargetType="{x:Type Button}">              
  <Setter Property="Control.Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type Button}">        
        <Button Style="{DynamicResource App_button}" >
          <Hyperlink Style="{DynamicResource Button_LinkForeground}" NavigateUri="{Binding Path=Tag, RelativeSource={RelativeSource Mode=TemplatedParent, AncestorLevel=0}}">
            <InlineUIContainer>
              <TextBlock Text="{Binding Path=Content, RelativeSource={RelativeSource Mode=TemplatedParent, AncestorLevel=0}}" />
            </InlineUIContainer>
          </Hyperlink>
        </Button>
      </ControlTemplate>
    </Setter.Value>
  </Setter>     
</Style>

In this everything is working fine, but when I do the same for MenuItem the text for the MenuItem dissappears.

The xaml for MenuItem is like this

<MenuItem x:Name="MenuItem1" Style="{StaticResource User_Hyperlink_MenuItem}" Tag="123456789.XAML" Header="MenuItem1" />

The style is like this

<Style x:Key="User_Hyperlink_MenuItem" TargetType="{x:Type MenuItem}">              
  <Setter Property="Control.Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type MenuItem}">        
        <MenuItem Style="{DynamicResource App_MenuItem}"  >
          <Hyperlink Style="{DynamicResource Menu_LinkForeground}" NavigateUri="{Binding Path=Tag, RelativeSource={RelativeSource Mode=TemplatedParent, AncestorLevel=0}}">
            <InlineUIContainer>
              <TextBlock Text="{Binding Path=Header, RelativeSource={RelativeSource Mode=TemplatedParent, AncestorLevel=0}}" />
            </InlineUIContainer>
          </Hyperlink>
        </MenuItem>
      </ControlTemplate>
    </Setter.Value>
  </Setter>     
</Style>

I have also changed the style like this

...
<TextBlock Text="{Binding Path=Content, RelativeSource={RelativeSource Mode=TemplatedParent, AncestorLevel=0}}" />
...

but it is not working. I need to fix this by modifying the style only and cannot change the xaml for MenuItem due to some limitation.

Update 1

I need to make MenuItem text appear on it. The text is there in the TextBlock but its value is coming from the Content Property of MenuItem. MenuItem does not have a Content property instead it has Items Collection that is why the text is not showing. Whereas in the case of Button everything is working the link, text all.

I am working on loose XAML so I have to use Hyperlink for linking. No need to worry about recursion or inheritance as its not an issue. The problem is only that there is no Content property for MenuItem so need to solve this by getting the Item[0].

Update 2

I am also providing the other Resources for reference

<Style x:Key="App_MenuItem" TargetType="{x:Type MenuItem}">
 <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
 <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
 <Setter Property="Background" Value="#FF015DAB"/>
 <Setter Property="Foreground" Value="White"/>
 <Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=SubmenuItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
 <Style.Triggers>
   <Trigger Property="Role" Value="TopLevelHeader">
     <Setter Property="Margin" Value="0,1,0,1"/>
     <Setter Property="Padding" Value="6,3,6,3"/>
     <Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=TopLevelHeaderTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
   </Trigger>
   <Trigger Property="Role" Value="TopLevelItem">
      <Setter Property="Margin" Value="0,1,0,1"/>
      <Setter Property="Padding" Value="6,3,6,3"/>
      <Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=TopLevelItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
   </Trigger>
   <Trigger Property="Role" Value="SubmenuHeader">
      <Setter Property="DockPanel.Dock" Value="Top"/>
      <Setter Property="Padding" Value="0,2,0,2"/>
      <Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=SubmenuHeaderTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
   </Trigger>
   <Trigger Property="Role" Value="SubmenuItem">
      <Setter Property="DockPanel.Dock" Value="Top"/>
      <Setter Property="Padding" Value="0,2,0,2"/>
   </Trigger>
 </Style.Triggers>
</Style>

<Style x:Key="Menu_LinkForeground" TargetType="{x:Type Hyperlink}">
 <Setter Property="Foreground" Value="White" />
 <Setter Property="TextDecorations" Value="None" />
</Style>
CodeMe
  • 89
  • 2
  • 13
  • Do you have all DynamicResource's available? –  Jan 05 '12 at 09:43
  • Yes all resources are available. – CodeMe Jan 05 '12 at 10:23
  • Try replace you stule with something really simplistic like a Button with no bindings and see if it'll pick it up at all. –  Jan 05 '12 at 10:26
  • The scenario is working for Buttons perfectly, but for MenuItem it is not working. – CodeMe Jan 05 '12 at 11:02
  • :) Sorry, what I was meant to say - if you try applying your style to MenuItem, but remove everything from the ControlTemplate leaving it with just a Button. –  Jan 05 '12 at 11:11
  • In the `ControlTemplate` of `MenuItem` there is no `Button` – CodeMe Jan 05 '12 at 11:33
  • I know that, I just wanted to illiminate the possibility of something with the template prevents from its correct application:) –  Jan 05 '12 at 11:45
  • I don't understand what you want me to do. I have removed all dynamic resources and the result is the same. – CodeMe Jan 05 '12 at 11:51

1 Answers1

0

You are using an incorrect style for the MenuItem. Your style's template cannot reference the object itself as it creates a circular reference. Just use the Hyperlink as a root visual in the control template.

Update 1 - I was wring in saying that referencing a control itself from withing its template doesn't work. It works. it injects the custom stuff writin inside the default template.

It still doesn't make much sense though.


Here's the working version for a MenuItem (note, I stripped off all resources from the template as I don't have them). Just add your resources one by one and see at what stage it'll stop working.

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.Resources>
            <Style x:Key="User_Hyperlink_MenuItem" TargetType="{x:Type MenuItem}">
                <Setter Property="Control.Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type MenuItem}">
                            <MenuItem>
                                <Button>ABC</Button>
                            </MenuItem>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Grid.Resources>
        <MenuItem Style="{StaticResource User_Hyperlink_MenuItem}">A</MenuItem>        
    </Grid>
</Window>

Just for a reference, here's the default MenuItem's style:

<Style TargetType="{x:Type MenuItem}" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib">
    <Style.Triggers>
        <Trigger Property="MenuItem.Role">
            <Setter Property="Control.Padding">
                <Setter.Value>
                    <Thickness>
                        7,2,8,3</Thickness>
                    </Setter.Value>
                </Setter>
            <Setter Property="Control.Template">
                <Setter.Value>
                    <DynamicResource ResourceKey="{ComponentResourceKey TypeInTargetAssembly=MenuItem, ResourceId=TopLevelHeaderTemplateKey}" />
                    </Setter.Value>
                </Setter>
            <Trigger.Value>
                <x:Static Member="MenuItemRole.TopLevelHeader" />
                </Trigger.Value>
            </Trigger>
        <Trigger Property="MenuItem.Role">
            <Setter Property="Control.Padding">
                <Setter.Value>
                    <Thickness>
                        7,2,8,3</Thickness>
                    </Setter.Value>
                </Setter>
            <Setter Property="Control.Template">
                <Setter.Value>
                    <DynamicResource ResourceKey="{ComponentResourceKey TypeInTargetAssembly=MenuItem, ResourceId=TopLevelItemTemplateKey}" />
                    </Setter.Value>
                </Setter>
            <Trigger.Value>
                <x:Static Member="MenuItemRole.TopLevelItem" />
                </Trigger.Value>
            </Trigger>
        <Trigger Property="MenuItem.Role">
            <Setter Property="Control.Padding">
                <Setter.Value>
                    <Thickness>
                        2,3,2,3</Thickness>
                    </Setter.Value>
                </Setter>
            <Setter Property="Control.Template">
                <Setter.Value>
                    <DynamicResource ResourceKey="{ComponentResourceKey TypeInTargetAssembly=MenuItem, ResourceId=SubmenuHeaderTemplateKey}" />
                    </Setter.Value>
                </Setter>
            <Trigger.Value>
                <x:Static Member="MenuItemRole.SubmenuHeader" />
                </Trigger.Value>
            </Trigger>
        <Trigger Property="MenuItem.Role">
            <Setter Property="Control.Padding">
                <Setter.Value>
                    <Thickness>
                        2,3,2,3</Thickness>
                    </Setter.Value>
                </Setter>
            <Trigger.Value>
                <x:Static Member="MenuItemRole.SubmenuItem" />
                </Trigger.Value>
            </Trigger>
        </Style.Triggers>
    <Style.Resources>
        <ResourceDictionary />
        </Style.Resources>
    <Setter Property="Control.HorizontalContentAlignment">
        <Setter.Value>
            <Binding Path="HorizontalContentAlignment" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ItemsControl, AncestorLevel=1}" />
            </Setter.Value>
        </Setter>
    <Setter Property="Control.VerticalContentAlignment">
        <Setter.Value>
            <Binding Path="VerticalContentAlignment" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ItemsControl, AncestorLevel=1}" />
            </Setter.Value>
        </Setter>
    <Setter Property="Panel.Background">
        <Setter.Value>
            <SolidColorBrush>
                #00FFFFFF</SolidColorBrush>
            </Setter.Value>
        </Setter>
    <Setter Property="ScrollViewer.PanningMode">
        <Setter.Value>
            <x:Static Member="PanningMode.Both" />
            </Setter.Value>
        </Setter>
    <Setter Property="Stylus.IsFlicksEnabled">
        <Setter.Value>
            <s:Boolean>
                False</s:Boolean>
            </Setter.Value>
        </Setter>
    <Setter Property="Control.Template">
        <Setter.Value>
            <DynamicResource ResourceKey="{ComponentResourceKey TypeInTargetAssembly=MenuItem, ResourceId=SubmenuItemTemplateKey}" />
            </Setter.Value>
        </Setter>
    </Style>
  • But I am already using this kind of reference for Button and Label. The Hyperlink cannot be used as a root visual because it is not FrameworkElement or derived type. – CodeMe Jan 05 '12 at 14:02
  • @CodeMe That it wrong. The template shouldn't refer to the control itself, it makes no sense. You're using Menuitem as a spare part to build Menuitem - how is it supposed to work? –  Jan 05 '12 at 14:40
  • How do I apply `Style="{DynamicResource App_MenuItem}"` on MenuItem then? because without this the text is coming plain. – CodeMe Jan 05 '12 at 15:07
  • Control templates weren't really designed for inheritance. What are you trying to achieve anyway? Did you get resourceless sample working? –  Jan 05 '12 at 15:11
  • The sample you have posted is working but the text is coming plain. If you could somehow apply the `Style="{DynamicResource App_MenuItem}"` on MenuItem then the problem would be solved – CodeMe Jan 06 '12 at 06:40
  • If it works, then there's somethign wrong with your App_MenuItem - it's enither unavailable or rmisses one of its deps –  Jan 06 '12 at 09:12
  • App_MenuItem is fine. I have updated the post for more information. I need a Hyperlink under the MenuItem so that it can goto the provided Uri – CodeMe Jan 06 '12 at 10:10