You can use DataTrigger to fire a popup to do a similar work.
For example:
Window1.xaml
window1.xaml.cs
UtilityMethods.cs
MyBusinessObject.cs
For example:
Window1.xaml
<Window |
x:Class="WpfApplication1.Window1" |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
xmlns:local="clr-namespace:WpfApplication1" |
Title="Window1" |
Height="184" |
Width="366"> |
<Window.Resources> |
<HierarchicalDataTemplate |
DataType="{x:Type local:MyBusinessObject}" |
ItemsSource="{Binding Path=Children}"> |
<Border Margin="5" BorderThickness="1" BorderBrush="Gray" CornerRadius="7"> |
<Grid x:Name="myGrid"> |
<ContentPresenter |
Content="{Binding MenuText}" |
Loaded="ContentPresenter_Loaded" |
RecognizesAccessKey="True" /> |
<Popup |
IsOpen="False" |
Visibility="Collapsed" |
PlacementTarget="{Binding ElementName=myGrid}" |
Placement="Bottom" |
x:Name="myPopup"> |
<TextBlock |
Name="Expanded" |
Visibility="Hidden" |
Text="{Binding MenuText}" |
FontSize="14" |
Background="LightGreen" /> |
</Popup> |
</Grid> |
</Border> |
<HierarchicalDataTemplate.Triggers> |
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, |
AncestorType={x:Type MenuItem}}, |
Path=IsPressed}" Value="true"> |
<DataTrigger.Setters> |
<Setter TargetName="Expanded" Property="Visibility" Value="Visible"/> |
<Setter TargetName="myPopup" Property="IsOpen" Value="True"/> |
</DataTrigger.Setters> |
</DataTrigger> |
</HierarchicalDataTemplate.Triggers> |
</HierarchicalDataTemplate> |
</Window.Resources> |
<Grid |
Margin="10" Width="280"> |
<Grid.RowDefinitions> |
<RowDefinition Height="Auto" /> |
<RowDefinition Height="Auto" MinHeight="20" /> |
</Grid.RowDefinitions> |
<Menu |
ItemsSource="{Binding}"/> |
<StackPanel |
Grid.Row="1" Height="20.277" HorizontalAlignment="Left" VerticalAlignment="Top" Width="282"> |
<Button |
Width="120" |
Content="Toggle Enable" |
Click="Enable_Click" /> |
</StackPanel> |
</Grid> |
</Window> |
window1.xaml.cs
using System; |
using System.Collections.ObjectModel; |
using System.Windows; |
using System.Windows.Controls; |
using System.Windows.Data; |
namespace WpfApplication1 |
{ |
public partial class Window1 : Window |
{ |
private ObservableCollection<MyBusinessObject> _options; |
public Window1() |
{ |
InitializeComponent(); |
_options = new ObservableCollection<MyBusinessObject>(); |
// build simple menu structure |
MyBusinessObject menuTwo = new MyBusinessObject |
{ |
MenuText = "Two", |
}; |
menuTwo.Children.Add( |
new MyBusinessObject |
{ |
MenuText = "Child 1" |
} |
); |
menuTwo.Children.Add( |
new MyBusinessObject |
{ |
MenuText = "Child 2", |
IsEnabled = false |
} |
); |
_options.Add( |
new MyBusinessObject |
{ |
MenuText = "One" |
} |
); |
_options.Add(menuTwo); |
DataContext = _options; |
} |
private void ContentPresenter_Loaded(object sender, RoutedEventArgs e) |
{ |
// get the content presenter |
ContentPresenter contentPresenter = |
sender as ContentPresenter; |
// get reference to menu item |
MenuItem menuItem = |
UtilityMethods.FindParent<MenuItem>(contentPresenter); |
// get reference to business object |
MyBusinessObject myBusinessObject = |
menuItem.DataContext as MyBusinessObject; |
// create bindings |
Binding isEnabledBinding = new Binding("IsEnabled"); |
isEnabledBinding.Mode = BindingMode.TwoWay; |
isEnabledBinding.Source = myBusinessObject; |
menuItem.SetBinding(MenuItem.IsEnabledProperty, isEnabledBinding); |
Binding commandBinding = new Binding("Command"); |
commandBinding.Mode = BindingMode.TwoWay; |
commandBinding.Source = myBusinessObject; |
menuItem.SetBinding(MenuItem.CommandProperty, commandBinding); |
} |
private void Enable_Click(object sender, RoutedEventArgs e) |
{ |
// toggle IsEnabled |
_options[1].Children[1].IsEnabled = |
!_options[1].Children[1].IsEnabled; |
} |
} |
} |
using System; |
using System.Windows; |
using System.Windows.Media; |
namespace WpfApplication1 |
{ |
public class UtilityMethods |
{ |
public static T FindVisualChild<T>(DependencyObject element) where T : DependencyObject |
{ |
int count = VisualTreeHelper.GetChildrenCount(element); |
for (int i = 0; i < count; i++) |
{ |
DependencyObject child = VisualTreeHelper.GetChild(element, i); |
T childchildAsT = child as T; |
if (childAsT != null) |
{ |
return childAsT; |
} |
T obj = FindVisualChild<T>(child); |
if (obj != null) |
{ |
return obj; |
} |
} |
return null; |
} |
public static T FindParent<T>(DependencyObject childElement) where T : DependencyObject |
{ |
return FindParent<T>(childElement, 0); |
} |
public static T FindParent<T>(DependencyObject childElement, int depth) where T : DependencyObject |
{ |
DependencyObject parent = VisualTreeHelper.GetParent(childElement); |
T parentparentAsT = parent as T; |
if (parent == null) |
{ |
return null; |
} |
else if (parentAsT != null) |
{ |
if (depth == 0) |
{ |
return parentAsT; |
} |
depth -= depth; |
} |
return FindParent<T>(parent, depth); |
} |
} |
} |
using System; |
using System.Collections.ObjectModel; |
using System.ComponentModel; |
using System.Windows.Input; |
namespace WpfApplication1 |
{ |
public class MyBusinessObject : INotifyPropertyChanged |
{ |
private bool _isEnabled; |
private string _menuText; |
private ICommand _command; |
private ObservableCollection<MyBusinessObject> _children; |
public event PropertyChangedEventHandler PropertyChanged; |
public MyBusinessObject() |
{ |
IsEnabled = true; |
Children = new ObservableCollection<MyBusinessObject>(); |
} |
public string MenuText |
{ |
get { return _menuText; } |
set |
{ |
_menuText = value; |
RaisePropertyChanged("MenuText"); |
} |
} |
public bool IsEnabled |
{ |
get { return _isEnabled; } |
set |
{ |
_isEnabled = value; |
RaisePropertyChanged("IsEnabled"); |
} |
} |
public ICommand Command |
{ |
get { return _command; } |
set |
{ |
_command = value; |
RaisePropertyChanged("Command"); |
} |
} |
public ObservableCollection<MyBusinessObject> Children |
{ |
get { return _children; } |
set |
{ |
_children = value; |
} |
} |
private void RaisePropertyChanged(string propertyName) |
{ |
var handler = PropertyChanged; |
if (handler != null) |
{ |
handler(this, new PropertyChangedEventArgs(propertyName)); |
} |
} |
} |
} |