Search code examples
c#wpfxamlhoverstatusbar

WPF C# Statusbar label content from current control's tooltip


Ok, so I'm trying to figure out how to set a status bars label text to show information about the current control that a mouse is hovering over. I have seen this numerous times on many programs so I know it can be done and I'm sure there are explanations out there that could help me but I can't seem to find the right words to search for the answer unfortunately... The closest thing I could find was in the link below. I tried to utilize this but it gave me an error when I tried to set the text property.

Anyone have some information or a link to help me by chance? Thanks, Ryan

Display text in a label when hovering over a control without using events

My XAML Code:

<StatusBar>
            <StatusBar.ItemsPanel>
                <ItemsPanelTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="75" />
                        </Grid.ColumnDefinitions>

                        <Grid.RowDefinitions>
                            <RowDefinition Height="*" />
                        </Grid.RowDefinitions>
                    </Grid>
                </ItemsPanelTemplate>
            </StatusBar.ItemsPanel>
            <StatusBarItem Grid.Column="0">
                <Label Content="New Lead Inquiry" />
            </StatusBarItem>
            <Separator Grid.Column="1" Style="{StaticResource StylingStatusBarSeparator}" />
            <StatusBarItem Grid.Column="2">
                <Label x:Name="infoStatusBar" Content="Label for text about the currently hovered item" />
            </StatusBarItem>
            <Separator Grid.Column="3" Style="{StaticResource StylingStatusBarSeparator}" />
            <StatusBarItem Grid.Column="4">
                <Label Content="Not Saved" />
            </StatusBarItem>
        </StatusBar>

Solution

  • Here's a solution that doesn't require you to modify each child control or use any frameworks.

    This isn't really related to MVVM, since it's pure UI stuff. There's nothing here that would involve a viewmodel.

    Handle Window.PreviewMouseMove:

    MainWindow.xaml

    <Window 
        ...
        PreviewMouseMove="Window_PreviewMouseMove"
        >
    

    MainWindow.xaml.cs

    Define a dependency property of type Object, and in the preview mousemove handler, give it the nearest parent tooltip of the control the mouse is over:

        private void Window_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            var element = Mouse.DirectlyOver as FrameworkElement;
    
            HoverToolTip = GetTooltip(element);  
        }
    
        #region HoverToolTip Property
        public object HoverToolTip
        {
            get { return (object)GetValue(HoverToolTipProperty); }
            set { SetValue(HoverToolTipProperty, value); }
        }
    
        public static readonly DependencyProperty HoverToolTipProperty =
            DependencyProperty.Register(nameof(HoverToolTip), typeof(object), typeof(MainWindow),
                new PropertyMetadata(null));
        #endregion HoverToolTip Property
    
        protected static Object GetTooltip(FrameworkElement obj)
        {
            if (obj == null)
            {
                return null;
            }
            else if (obj.ToolTip != null)
            {
                return obj.ToolTip;
            }
            else
            {
                return GetTooltip(VisualTreeHelper.GetParent(obj) as FrameworkElement);
            }
        }
    

    And bind that to whatever in the XAML.

        <Label
            x:Name="StatusBar"
            Content="{Binding HoverToolTip, RelativeSource={RelativeSource AncestorType=Window}}"
            Grid.Row="2"
            />
    

    That Label is just the quickie I put in my test XAML. This binding is the important part there:

    {Binding HoverToolTip, RelativeSource={RelativeSource AncestorType=Window}}