【问题标题】:WPF tooltips from database来自数据库的 WPF 工具提示
【发布时间】:2013-03-12 01:36:17
【问题描述】:

我需要能够在运行时在 3 层 WPF 应用程序中编辑工具提示。 (这可能会允许管理员,而不是每个用户。)我想要的是在数据库中拥有工具提示,我一直在寻找各种技术来实现这一点。 Josh Smith 有一个使用工具提示转换器的好例子 (here)。但是,我需要将工具提示链接到各个 UI 控件,因此每个控件都必须具有唯一标识符。不幸的是,这不是 WPF 所要求的。我不想给每个控件一个名字。我记得您可以以某种方式生成 x:Uid,但不记得如何生成。另外,我想以某种方式连接到工具提示机制,而不是为每个控件定义一个转换器。我意识到我的目标可能有点高,但是有什么想法吗?

【问题讨论】:

  • 所以您的意思是可视化树中的任何 UI 元素都可能定义了工具提示?由最终用户定义?请张贴截图或图片来说明您的意思。

标签: wpf wpf-controls tooltip


【解决方案1】:

您可以使用VisualTreeHelper 类(msdn)。

在这个解决方案中,如果你想从 db 设置 ToolTip,你必须设置元素的名称。

首先你必须创建一个类来保存你的数据库中的数据:

class ToolTipContainer
{
    public string ElementName { get; set; }
    public string ToolTip { get; set; }       
}

接下来你应该使用VisualTreeHelper 来遍历所有元素:

class ToolTipManager
{
    List<ToolTipContainer> source;

    public ToolTipManager(List<ToolTipContainer> source)
    {
        this.source = source;
    }

    public void EnumVisual(Visual myVisual)
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(myVisual); i++)
        {                
            Visual childVisual = (Visual)VisualTreeHelper.GetChild(myVisual, i);                                 
            ((dynamic)childVisual).ToolTip = source.Where(x => x.ElementName == childVisual.GetValue(Control.NameProperty) as string).Select(x => x.ToolTip).FirstOrDefault();                                
            EnumVisual(childVisual);
        }
    }
}

使用示例:

<Window x:Class="WPFToolTipDB.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <StackPanel>
            <Button Name="Button" Content="Click me" />
            <TextBox MinWidth="150" />
            <Button Name="Button1" Content="Click me!" />
            <TextBlock Name="TextBlock" Text="My text block" />
            <StackPanel Orientation="Horizontal">
                <TextBlock Name="tbName" Text="Name:" />
                <TextBox Name="tbEnterName" MinWidth="150" />
            </StackPanel>
        </StackPanel>
    </Grid>
</Window>

代码隐藏:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        // When you don't specify name of the element you can set default ToolTip.
        source.Add(new ToolTipContainer { ElementName = string.Empty, ToolTip = "Empty ToolTip!!!" });
        source.Add(new ToolTipContainer { ElementName = "Button", ToolTip = "Click me" });
        source.Add(new ToolTipContainer { ElementName = "Button1", ToolTip = "Click me!" });
        source.Add(new ToolTipContainer { ElementName = "TextBlock", ToolTip = "My TextBlock" });
        source.Add(new ToolTipContainer { ElementName = "tbName", ToolTip = "Enter your name!" });
        source.Add(new ToolTipContainer { ElementName = "tbEnterName", ToolTip = "Please enter your name here!" });            

        var ttManager = new ToolTipManager(source);
        ttManager.EnumVisual(this.Content as Visual);
    }
    List<ToolTipContainer> source = new List<ToolTipContainer>();
}

【讨论】:

  • 太棒了,谢谢。您选择使用列表的任何原因,或者这只是为了演示目的?我正在考虑在启动时将工具提示加载到Dictionary
  • @Rubio 我选择List&lt;T&gt; 仅用于演示目的,您可以使用字典。但是,如果您使用我的解决方案,您可以以简单的方式扩展工具提示,可能是图片、谁编写了此工具提示、何时更改了工具提示等。
猜你喜欢
  • 2020-09-09
  • 2011-09-28
  • 1970-01-01
  • 2013-04-16
  • 2011-06-17
  • 1970-01-01
  • 1970-01-01
  • 2019-03-09
  • 1970-01-01
相关资源
最近更新 更多