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

时间:2017-09-01 16:37:28

标签: c# wpf xaml hover statusbar

好的,所以我试图找出如何设置状态栏标签文本以显示鼠标悬停在当前控件上的信息。我已经在很多节目上看过很多次,所以我知道可以做到这一点,我确信那里有解释可以帮助我,但我似乎找不到合适的词来搜索答案不幸... 我能找到的最接近的东西是在下面的链接中。我试图利用这个但是当我尝试设置text属性时它给了我一个错误。

任何人都有一些信息或链接可以帮助我吗? 谢谢, 莱恩

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>

2 个答案:

答案 0 :(得分:0)

您可以在控件上连接MouseEnterMouseLeave命令,在viewmodel中设置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>

在你的viewmodel中:

首先,添加HelpText和ICommands的属性:

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

然后在viewmodel构造函数中初始化ICommands以指向viewmodel中的方法:

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

Screenshot

答案 1 :(得分:0)

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

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

处理Window.PreviewMouseMove:

MainWindow.xaml

<Window 
    ...
    PreviewMouseMove="Window_PreviewMouseMove"
    >

MainWindow.xaml.cs

定义Object类型的依赖项属性,并在预览mousemove处理程序中,为它提供鼠标所在控件的最近父工具提示:

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

如果你愿意满足较少的样式点,你可以在没有依赖属性或绑定的情况下做到这一点:

MainWindow.xaml

    <Label
        x:Name="StatusBarLabel"
        Grid.Row="2"
        />

MainWindow.xaml.cs

    private void Window_PreviewMouseMove(object sender, MouseEventArgs e)
    {
        var element = Mouse.DirectlyOver as FrameworkElement;

        StatusBarLabel.Content = GetTooltip(element);  
    }

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