当前控件工具提示中的 WPF C# 状态栏标签内容

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

好的,所以我正在尝试弄清楚如何设置状态栏标签文本以显示有关鼠标悬停在其上的当前控件的信息。我已经在很多程序上看到过很多次,所以我知道这是可以做到的,而且我确信那里有可以帮助我的解释,但不幸的是,我似乎找不到合适的词来搜索答案...... 我能找到的最接近的东西是在下面的 link 中。我尝试使用它,但是当我尝试设置文本 属性.

时它给了我一个错误

任何人有一些信息或 link 可以帮助我吗? 谢谢, 瑞安

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

我的XAML代码:

<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>

您可以在控件上连接 MouseEnterMouseLeave 命令以在视图模型中设置 HelpText 属性,然后将状态栏标签绑定到 HelpText 这样当它被设置为新值时,新值会出现在状态栏中。

此答案使用 MVVM Light 工具包,但应该适用于任何 MVVM 设置:

在XAML中:

<Window x:Class="MvvmLightPlayground.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:ignore="http://www.galasoft.ch/ignore"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        mc:Ignorable="d ignore"
        Height="300"
        Width="600"
        Title="MVVM Light Application">


    <Window.DataContext>
        <Binding Path="Main" Source="{StaticResource Locator}" />
    </Window.DataContext>

    <StackPanel>
        <Label Content="This is Label1" x:Name="Label1">
            <!-- Triggers like this are easy to wire up using blend.  If you do it manually, add the i: definition to your window tag as shown above -->
            <i:Interaction.Triggers>
                <i:EventTrigger SourceName="Label1" EventName="MouseEnter">
                    <i:InvokeCommandAction Command="{Binding MouseEnter}" CommandParameter="This is Label1.  Look how neat it is!" />
                </i:EventTrigger>
                <i:EventTrigger SourceName="Label1" EventName="MouseLeave">
                    <i:InvokeCommandAction Command="{Binding MouseLeave}" CommandParameter="This is Label1.  Look how neat it is!" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Label>
        <Label Content="This is Label2" x:Name="Label2">
            <i:Interaction.Triggers>
                <i:EventTrigger SourceName="Label2" EventName="MouseEnter">
                    <i:InvokeCommandAction Command="{Binding MouseEnter}" CommandParameter="This is Label2.  It's a different label." />
                </i:EventTrigger>
                <i:EventTrigger SourceName="Label2" EventName="MouseLeave">
                    <i:InvokeCommandAction Command="{Binding MouseLeave}" CommandParameter="This is Label2.  It's a different label." />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Label>

        <StatusBar>
            <StatusBar.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </StatusBar.ItemsPanel>
            <StatusBarItem>
                <Label Content="{Binding HelpText, Mode=OneWay}" /> <!-- Bind to your HelpText property in the VM -->
            </StatusBarItem>
        </StatusBar>
    </StackPanel>
</Window>

在您的视图模型中:

首先,为您的 HelpText 和 ICommand 添加属性:

private string _helpText = "Testing";
public string HelpText
{
    get
    {
        return _helpText;
    }
    set
    {
        Set(() => HelpText, ref _helpText, value);
    }
}

private ICommand _mouseEnter;
public ICommand MouseEnter
{
    get
    {
        return _mouseEnter;
    }
    set
    {
        Set(() => MouseEnter, ref _mouseEnter, value);
    }
}

private ICommand _mouseLeave;
public ICommand MouseLeave
{
    get
    {
        return _mouseLeave;
    }
    set
    {
        Set(() => MouseLeave, ref _mouseLeave, value);
    }
}

然后在视图模型构造函数中初始化 ICommand 以指向视图模型中的方法:

public MainViewModel()
{
    MouseEnter = new RelayCommand<string>(SetHelpText);
    MouseLeave = new RelayCommand<string>(ClearHelpText);
}

然后创建您的辅助方法来设置 HelpText 属性:

public void SetHelpText(string helpText)
{
    HelpText = helpText;
}

public void ClearHelpText(string textToClear)
{
    // check to see whether it has already been set to something else by another MouseEnter event...
    if (HelpText == textToClear)
    {
        HelpText = "";
    }
}

这是鼠标悬停在 Label2 上时显示的 运行 示例:

这是一个不需要您修改每个子控件或使用任何框架的解决方案。

这与 MVVM 没有真正的关系,因为它是纯粹的 UI 东西。这里没有任何内容涉及视图模型。

句柄 Window.PreviewMouseMove:

MainWindow.xaml

<Window 
    ...
    PreviewMouseMove="Window_PreviewMouseMove"
    >

MainWindow.xaml.cs

定义对象类型的依赖项 属性,并在预览鼠标移动处理程序中,为其提供鼠标悬停的控件的最近的父工具提示:

    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);
        }
    }

并将其绑定到 XAML 中的任何内容。

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

那个标签只是我在测试中添加的快捷方式 XAML。这个绑定是那里的重要部分:

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