<ItemsControl ItemsSource="{Binding ViewModelOne.Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding X}"/>
<Setter Property="Canvas.Top" Value="{Binding Y}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate >
<ContentControl>
<StackPanel Orientation="Vertical">
<StackPanel.ContextMenu>
<ContextMenu >
<MenuItem Header="Delete" Command="{Binding ViewModelOne.DeleteCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MainWindow}}}" />
</ContextMenu>
</StackPanel.ContextMenu>
<TextBlock x:Name="Details" Text="{Binding Details}" />
<TextBlock x:Name="Name" Text="{Binding Name}" />
<Rectangle x:Name="Rects" Height="10" Width="10" Stroke="Black" StrokeThickness="1" />
</StackPanel>
</ContentControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
I have the above part of the code in my project and am trying to bind the Contextmenu command, what is the correct way.
I have also tried
<MenuItem Header="Delete" Command="{Binding PlacementTarget.Tag.DeleteCommand, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ContextMenu}}" />
Still i couldnot get the command working
Instead of putting ContextMenu on the your StackPanel, set ContextMenu on your Item in ItemContainerStyle and also set the Tag for the Item to the parents DataContext.
<ItemsControl x:Name="MyItemControl" ItemsSource="{Binding ViewModelOne.Items}">
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Tag" Value="{Binding DataContext, ElementName=MyItemControl}"></Setter>
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu >
<MenuItem Header="Delete" Command="{Binding PlacementTarget.Tag.ViewModelOne.DeleteCommand, RelativeSource={RelativeSource Self}}" />
</ContextMenu>
</Setter.Value>
</Setter>
<Setter Property="Canvas.Left" Value="{Binding X}"/>
<Setter Property="Canvas.Top" Value="{Binding Y}"/>
</Style>
</ItemsControl.ItemContainerStyle>
Related
I try to bind itemssource (collection in collection) to context menu and i want to take a context menu item through click (MVVM)Caliburn
<TreeView x:Name="TreeViewName" BorderThickness="0" ItemsSource="{Binding RegionsTree}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<RadioButton Tag="{Binding DataContext, ElementName=TreeViewName}" Content="{Binding Name}"
cal:Message.Attach="[Click]=[ShowItemScreen($dataContext)];[PreviewMouseRightButtonDown]=[Action OnContextMenuOpening($source)]"
GroupName="TestTree">
<RadioButton.ContextMenu>
<ContextMenu ItemsSource="{Binding RegionCategories}" cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<ContextMenu.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="MenuItem.Header" Value="{Binding Name}" />
<Setter Property="MenuItem.ItemsSource" Value="{Binding Commands}" />
<Setter Property="cal:Message.Attach" Value="[Action ContextMenuItemClick($eventArgs)]"/>
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
</RadioButton.ContextMenu>
</RadioButton>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
<TreeView.ItemContainerStyle >
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="True"/>
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
I've setup a ListView with grouping and I would like to retrieve the GroupName when I right click on the group in MVVM. I've placed a ContextMenu on my group style, and I was trying to use the EventToCommand from System.Windows.Interactivity to get the underlying item.
Here the relevant part:
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander IsExpanded="False" Template="{StaticResource CustomizedExpander}" Background="#FFEBEBEB" BorderThickness="0" ContextMenu="{StaticResource GroupContextMenu}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseRightButtonDown">
<i:InvokeCommandAction Command="{Binding Path=OnCategorySelected}" CommandParameter="{Binding Name}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Expander.Header>
<StackPanel Orientation="Horizontal">
<!--N.B. The "Name" property is part of the CollectionViewSource-->
<TextBlock Text="{Binding Name}" FontWeight="Bold" Foreground="#FF767676" VerticalAlignment="Bottom" />
<TextBlock Text="{Binding ItemCount}" Foreground="#FF454545" FontWeight="Bold" FontStyle="Italic" Margin="10,0,0,0" VerticalAlignment="Bottom" />
<TextBlock Text=" item(s)" Foreground="#FF767676" FontStyle="Italic" VerticalAlignment="Bottom" />
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
I don't know if it's the right way to do it but it seems the command is not triggered at all.
Any suggestion?
UPDATE:
The whole thing was much simpler than I thought. The interaction part was not required at all. Fixing the binding is enough to get the underlying category when the context menu is shown:
<ListView ItemsSource="{Binding Modifications}" SelectedItem="{Binding SelectedItem}">
<ListView.Resources>
<ContextMenu x:Key="ItemContextMenu">
<MenuItem Header="Execute" Command="{Binding Path=DataContext.OnExecuteScript, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}" Background="WhiteSmoke" Visibility="{Binding CanExecute, Converter={StaticResource BooleanToVisibilityConverter}}" />
<MenuItem Header="Execute up to this" Command="{Binding Path=DataContext.OnExecuteScriptUpToThis, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}" Background="WhiteSmoke" Visibility="{Binding CanOnlyBeExecutedSequentially, Converter={StaticResource BooleanToVisibilityConverter}}" />
<MenuItem Header="Drop" Command="{Binding Path=DataContext.OnExecuteDrop, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}" Visibility="{Binding Drop, Converter={StaticResource BooleanToVisibilityConverter}}" Background="WhiteSmoke" />
<MenuItem Header="Dump" Command="{Binding Path=DataContext.OnExecuteDump, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}" Visibility="{Binding CanDump, Converter={StaticResource BooleanToVisibilityConverter}}" Background="WhiteSmoke" />
</ContextMenu>
<ContextMenu x:Key="GroupContextMenu">
<MenuItem Header="Dump all" Command="{Binding Path=DataContext.OnExecuteDumpAll, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}" CommandParameter="{Binding Name}" Background="WhiteSmoke" />
</ContextMenu>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn Header="Type" Width="120" DisplayMemberBinding="{Binding Type}" />
<GridViewColumn Header="Object Name" Width="Auto" DisplayMemberBinding="{Binding DisplayName}" />
<GridViewColumn Header="" Width="50">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Deploy}" IsHitTestVisible="False" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Object Name" Width="300" DisplayMemberBinding="{Binding ObjectName}" />
</GridView>
</ListView.View>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}" BasedOn="{StaticResource MetroListViewItem}" >
<Setter Property="ContextMenu" Value="{StaticResource ItemContextMenu}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Drop}" Value="True">
<Setter Property="Foreground" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="ContextMenu" Value="{StaticResource GroupContextMenu}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander IsExpanded="False" Template="{StaticResource CustomizedExpander}" Background="#FFEBEBEB" BorderThickness="0">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<!--N.B. The "Name" property is part of the CollectionViewSource-->
<TextBlock Text="{Binding Name}" FontWeight="Bold" Foreground="#FF767676" VerticalAlignment="Bottom" />
<TextBlock Text="{Binding ItemCount}" Foreground="#FF454545" FontWeight="Bold" FontStyle="Italic" Margin="10,0,0,0" VerticalAlignment="Bottom" />
<TextBlock Text=" item(s)" Foreground="#FF767676" FontStyle="Italic" VerticalAlignment="Bottom" />
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
First of all, i think i've figured out why your Command isnt firing.
Since you are in an Template, the DataContext has Changed. Therefore your CommandBinding should look like this:
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}, Path=DataContext.OnCategorySelected}" CommandParameter="{Binding}"/>
Also, your CommandParameter should not be Name because you'll only get a string in the end instead the whole Object.
If you use my above code you will get the whole CollectionViewGroup instead. In said CollectionViewGroup you'll find all the Items in the group. If you are fine with getting just the Groupname you can proceed with you implementation of course.
I dont really understand why you are using a ContextMenu and what it does (Since you dont posted that code), but if you are interested in how you can display the grouped Items in such a ContextMenu, you can do it like this:
<Expander IsExpanded="False" Background="#FFEBEBEB" BorderThickness="0" >
<Expander.ContextMenu>
<ContextMenu ItemsSource="{Binding Items}"/>
</Expander.ContextMenu>
</Expander>
Since we now know, what we have to deal with (It's still an CollectionViewGroup) we can set the Items of it as ItemsSource of the ContextMenu.
Hope this helps!
I have the following definition of a UserControl
<UserControl x:Class="Logger.View.AdvancedToggleButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:converter="clr-namespace:Logger.Converter"
xmlns:commonControls="clr-namespace:Logger.CommonControls"
mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<UserControl.Resources>
<converter:CountToVisibilityConverter x:Key="CountToVisibilityConverter" />
</UserControl.Resources>
<ItemsControl ItemsSource="{Binding LogElements, UpdateSourceTrigger=PropertyChanged}">
<ItemsControl.Resources>
<Style TargetType="{x:Type ToggleButton}" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border HorizontalAlignment="Center" VerticalAlignment="Center" x:Name="container"
BorderThickness="1" Margin="1,2,1,1" Padding="2,2,4,2" BorderBrush="Black">
<ContentPresenter x:Name="contentPresenter" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" TargetName="container" Value="{Binding SelectionBrush, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"/>
<Setter Property="BorderThickness" TargetName="container" Value="1,1,1,0"></Setter>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Background" TargetName="container" Value="{Binding SelectionBrush, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"/>
<Setter Property="Background" Value="{Binding SelectionBrush, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<ToggleButton Margin="2,1"
IsChecked="{Binding IsSelected, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
Command="{Binding DataContext.ToggleCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"
CommandParameter="{Binding}">
<ToggleButton.Content>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}" VerticalAlignment="Center" Margin="4,0,5,0" x:Name="tbText"/>
<Border Grid.Column="1" Margin="0,-1,-3,-1" MinWidth="20"
VerticalAlignment="Stretch" HorizontalAlignment="Center"
Background="Yellow" BorderBrush="LightGray" BorderThickness="1,0,0,0"
Visibility="{Binding WarningCount, Converter={StaticResource CountToVisibilityConverter}}"
Cursor="Hand">
<commonControls:ActionLink HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding WarningCount}"
FontFamily="Consolas" Margin="2,0" Command="{Binding DataContext.NavigateToWarningCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"/>
</Border>
<Border Grid.Column="2" Margin="3,-1,-3,-1" MinWidth="20"
VerticalAlignment="Stretch" HorizontalAlignment="Center"
Background="Red" BorderBrush="LightGray" BorderThickness="1,0,0,0"
Visibility="{Binding ErrorCount, Converter={StaticResource CountToVisibilityConverter}}"
Cursor="Hand" >
<commonControls:ActionLink HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding ErrorCount}"
FontFamily="Consolas" Foreground="White" Margin="2,0" />
</Border>
</Grid>
</ToggleButton.Content>
</ToggleButton>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</UserControl>
Everything just works fine. Now I've added another Property to this UserControl to set the BackgroundColor of the Checked ToggleButton-TextBlock (tbText) to a given SolidColorBrush.
My problem now is, that I have no idea how to correctly set the Trigger for this.
I tried to add the Trigger to the ControlTemplate.Triggers when the IsChecked is True. But I don't know how to access tbText from this point. Is this the correct location for the Trigger or do I have to add another Trigger at a lower level?
Your ToggleButton.IsChecked property is data bound to your IsSelected property so by default, you also want to set the TextBlock.Background when this IsSelected property is true. You can do that like this:
<TextBlock Text="{Binding Name}" VerticalAlignment="Center" Margin="4,0,5,0"
x:Name="tbText">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected}" Value="True">
<Setter Property="Background" Value="{Binding YourColourBrush,
RelativeSource={RelativeSource AncestorType={x:Type
YourPrefix:YourUserControl}}}" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
Alternatively, you could just data bind directly to the ToggleButton.IsChecked property like this:
<TextBlock Text="{Binding Name}" VerticalAlignment="Center" Margin="4,0,5,0"
x:Name="tbText">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, RelativeSource={RelativeSource
AncestorType={x:Type ToggleButton}}}" Value="True">
<Setter Property="Background" Value="{Binding YourColourBrush,
RelativeSource={RelativeSource AncestorType={x:Type
YourPrefix:YourUserControl}}}" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
Let's say I have a View/Page something like below:
Category1 Category2 ......... Category(n)
Tile1 Tile1 Tile1
Tile2 Tile2 Tile2
..... ..... .....
..... ..... .....
Tile(n) Tile(n) Tile(n)
The XAML used to Create the above OutPut:
<ItemsControl ItemsSource="{Binding MenuCategories}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel IsItemsHost="True" Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Height="500">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding Title}" FontSize="30" />
<ListBox Grid.Row="1" x:Name="lst"
ItemsSource="{Binding ??????}" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" Orientation="Vertical" MaxHeight="{Binding ElementName=lst, Path=ActualHeight}"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Width" Value="250" />
<Setter Property="Height" Value="125" />
<Setter Property="Margin" Value="2.5" />
<Setter Property="Padding" Value="2.5" />
<Setter Property="Background" Value="{Binding DataContext.Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}, Converter={StaticResource stringToBrushConverter}}" />
<Setter Property="Foreground" Value="White" />
<Setter Property="VerticalContentAlignment" Value="Bottom" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="{Binding DataContext.Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}, Converter ={StaticResource stringToBrushConverter}}" />
</Trigger>
</Style.Triggers>
</Style>
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="125" Width="250">
<Path Data="{Binding DataContext.ImageData, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}}" VerticalAlignment="Center"
Stretch="Uniform" Fill="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"
Width="68" Height="68" Margin="10" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<TransformGroup>
<TransformGroup.Children>
<RotateTransform Angle="0" />
<ScaleTransform ScaleX="1" ScaleY="1" />
</TransformGroup.Children>
</TransformGroup>
</Path.RenderTransform>
</Path>
<TextBlock Text="{Binding Title, Converter={StaticResource spaceToNewLineConverter}}" VerticalAlignment="Top"
Margin="40,10,10,10" FontSize="24" Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
But the problem is that I don't know the binding of ItemsSource of the ListBox. So, I don't get the Output as shown above.
Here is how my database tables look like:
You can simply bind to Design_Master_Category that store collection of Design_Master_TileItems, for example :
......
<ListBox Grid.Row="1" x:Name="lst"
ItemsSource="{Binding Design_Master_TileItems} >
......
If you find that the property is empty at run-time as stated in comment, it means the problem is not at your binding. You need to fix your query. I am by no means well-experienced with EF, but here is my suggestion :
try to use .Include(o => o.Design_Master_TileItems) function when querying Design_Master_Category table. [Reference]
I got the following code :
<HierarchicalDataTemplate x:Key="AssignedRate" ItemsSource="{Binding Children}" DataType="{x:Type local:UnitRateCatElement}">
<ContentControl>
<ContentControl.Template>
<ControlTemplate>
<StackPanel Tag="{Binding DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}">
<TextBlock Text="{Binding Category.Description}" />
<StackPanel.ContextMenu>
<ContextMenu>
<MenuItem Header="Add Unit Rate"
Command="{Binding Path=PlacementTarget.Tag.AddUnitRateCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
</ContextMenu>
</StackPanel.ContextMenu>
</StackPanel>
</ControlTemplate>
</ContentControl.Template>
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsDefined, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}}" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<TextBlock Text="Hello, it works!" />
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</HierarchicalDataTemplate>
The binding in the line : <DataTrigger Binding="{Binding Path=IsDefined, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}}" Value="True">
is incorrect (VS says so). How can I get this to work? The class local:UnitRateCatElement does have a IsDefined property. But I cannot get the binding right to point to that object. How can I get this binding right?
Try
Binding="{Binding Path=DataContext.IsDefined, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}}"
I think you should be doing this -
<DataTrigger Binding="{Binding Path=DataContext.IsDefined,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type TreeViewItem}}}" Value="True">
as your RelativeSource binding points to the TreeViewItem, which doesn't have IsDefined property, it is present in the DataContext of the TreeViewItem.
Update:
For your second problem (trigger not working), this is happening because you are setting the Template explicitly i.e. Local Value which is having higher precedence then Triggers; this should work -
<ControlTemplate x:Key="DefaultTemplate">
<StackPanel Tag="{Binding DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}">
<TextBlock Text="{Binding Category.Description}" />
<StackPanel.ContextMenu>
<ContextMenu>
<MenuItem Header="Add Unit Rate"
Command="{Binding Path=PlacementTarget.Tag.AddUnitRateCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
</ContextMenu>
</StackPanel.ContextMenu>
</StackPanel>
</ControlTemplate>
<ControlTemplate x:Key="DefinedTemplate">
<TextBlock Text="Hello, it works!" />
</ControlTemplate>
<HierarchicalDataTemplate x:Key="AssignedRate" ItemsSource="{Binding Children}"
DataType="{x:Type local:UnitRateCatElement}">
<ContentControl>
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="Template" Value={StaticResource DefaultTemplate}>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=DataContext.IsDefined, RelativeSource=
{RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}}"
Value="True">
<Setter Property="Template" Value={StaticResource DefinedTemplate}>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</HierarchicalDataTemplate>