Question

This is regards to MVVM & WPF -showing dynamic tooltip based on mouse location on a WPF Treeviewitems. Let say when the user hovers over a node which has got some business data based on that it should display tooltip.

Example: let say If i hover over manager items..should say -"locked" and for others "Ready to edit"..etc. Depends on the mouse over items data..tooltip text should guide the user to do further action. I'm trying to do some VM setting of tooltip text with the help of Tooltip opening event of TreeViewitem and trying to update the tooltip text..but facing some issue.

What are all the best and simple way to do it. Tried behavior and end up with some error.

System.Windows.Markup.XamlParseException occurred
  Message="Cannot add content of type 'x.x.Views.CustomTreeView.TreeTooltipBehavior' to an object of type 'System.Windows.Interactivity.BehaviorCollection'.  Error at object 'x.x.x.Views.CustomTreeView.TreeTooltipBehavior' in markup file 'x.x.x.Views;component/mypage.xaml' Line 72 Position 53."
  Source="PresentationFramework"

Code:

<MyMyControls:ExtendedTreeView x:Name="MyTreeView" ItemsSource="{Binding MyDriveCollection}"
             ItemContainerStyle="{StaticResource TVStyleTemplate}">
            <MyMyControls:ExtendedTreeView.ItemTemplate>
                <HierarchicalDataTemplate DataType="{x:Type NavModel:TreeDataItem}" ItemsSource="{Binding MyDriveCollection}">
                    <MyControls:SimpleEditableTextBlock x:Name="TabLabel" Text="{Binding Path=MenuText, Mode=TwoWay}" 
                          ToolTip="{Binding MenuText,Mode=TwoWay}">
                    </MyControls:SimpleEditableTextBlock>
                </HierarchicalDataTemplate>
            </MyControls:ExtendedTreeView.ItemTemplate>
            <MyControls:ExtendedTreeView.ContextMenu>
                <ContextMenu ItemsSource="{Binding ContextMenuItems}">
                    <ContextMenu.ItemTemplate>
                        <DataTemplate>
                            <MenuItem Header="{Binding MenuText}"
                                      CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, 
                                      AncestorType={x:Type TreeView}},Path=SelectedItem}" Command="{Binding Command}">
                            </MenuItem>
                        </DataTemplate>
                    </ContextMenu.ItemTemplate>
                </ContextMenu>
            </MyControls:ExtendedTreeView.ContextMenu>
            <i:Interaction.Behaviors>
                <CustomTreeView:TreeTooltipBehavior CustomTreeView:ToolTipOpeningCommand="{Binding ToolTipOpeningCommand,Mode=TwoWay,diag:PresentationTraceSources.TraceLevel=High}" />
                <CustomTreeView:WorkspaceTreeViewContextMenuBehavior ContextMenuOpeningCommand="{Binding ContextMenuOpeningCommand}"/>
            </i:Interaction.Behaviors>
 </MyControls:ExtendedTreeView>

TreeTooltipBehavior.cs

 public class TreeTooltipBehavior : Behavior<ExtendedTreeViewItem>
    {
        protected override void OnAttached()
        {
            base.OnAttached();
            this.AssociatedObject.ToolTipOpening += new ToolTipEventHandler(AssociatedObject_ToolTipOpening);
        }

        void AssociatedObject_ToolTipOpening(object sender, ToolTipEventArgs e)
        {
            if (sender != null)
            {
                TreeDataItem hit = ((TreeDataItem) (((FrameworkElement) (sender)).DataContext));

                if (ToolTipOpeningCommand != null)
                {
                    ToolTipOpeningCommand.Execute(hit);
                }
            }
        }

        public static readonly DependencyProperty ToolTipOpeningCommandProperty = DependencyProperty.Register(
            "ToolTipOpeningCommand",
            typeof(ICommand),
            typeof(TreeTooltipBehavior),
            new PropertyMetadata(null));

        public ICommand ToolTipOpeningCommand
        {
            get { return (ICommand)GetValue(ToolTipOpeningCommandProperty); }
            set { SetValue(ToolTipOpeningCommandProperty, value); }
        }

    }

In my view model I'm expecting to handle the ToolTipOpeningCommand and declared enough to get the event via Behavior class.

interestingly the contextmenu behavior works fine but tooltip behavior throws xaml parser exception..

1) Am i defined at the right place (for behavior) ? 2) If Contextmenu behavior works then why not tooltipbehavior ? 3) Any clue from the exception pasted at the top ?

I'm expecting to, (Xaml)-tooltip behavior -> to invoke tooltipopening event in the (behavior class) -> which in turns invoke the command defined in the ViewModel. I tried this similar way for context menu and works fine.

Pls provide some hint about fixing this issue.

Was it helpful?

Solution

The XAML parser error is because you are trying to attach a Behavior that only applies to ExtendedTreeViewItem to an ExtendedTreeView element. In other words, if you change Behavior<ExtendedTreeViewItem> to Behavior<ExtendedTreeView>, you will fix the parse error.

Although we cannot see from the code you presented, the reason the ContextMenu works is probably because WorkspaceTreeViewContextMenuBehavior derives from a Behavior with a generic type parameter that is compatible with ExtendedTreeView, such as FrameworkElement.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top